Swing Transparentes JPanel, Schrift verschmiert

Bernd B.

Mitglied
Hallo, da ich ein Menü grafisch animieren will, bin ich auf folgenden Fehler gestoßen:

Ich habe ein JPanel welches transparent ist (also mit Alphawert) und momentan drei JLabels enthält. Auf den JLabels liegt eine Mouseover-Funktion, die wenn man sich mit der Maus über ein JLabel befindet, die Schrift rot einfärbt.
Dieses JPanel will ich am bildschirm verschieben bzw. ins Fenster hineinfliegen lassen (so wie im MS Powerpoint die Überschriften), dies funktioniert auch ohne Probleme.

Mein Problem liegt darin, dass nachdem das JPanel hereingeflogen ist und ich über die JLabels fahre, wird die Schrift durch das mouseover seltsam verzogen (die Schrift ist dann nicht schön rot wie es sein sollte sondern die Schrift wird dabei "verschmiert").

25ge5au.jpg


Wenn ich das JPanel in denen die JLabels liegen keinen Alphawert zuweise, funktioniert dies ohne Probleme (bei der Schrift funktioniert alles korrekt). :autsch:
Doch nun meine Frage was muss ich tun um das JPanel weiter transparent zu lassen und trotzdem die Mouseover über den JLabels zu verwenden?
 
Zuletzt bearbeitet von einem Moderator:
Kannst mal etwas Code zeigen? Am besten einen kurzen kombilierbarer Beispielcode mit dem das Problem reproduziert werden kann.
Überschreibst Du in einzelnen Komponenten die paint bzw. paintComponent Methode?
 
Ja, die paintComponent-Methode sollte i.a. mit
Code:
@Override
protected void paintComponent(Graphics g)
{
    [b]super.paintComponent(g);[/b]

    // Hier jetzt dein Code:
    ...
anfangen.
 
Mein Code sieht so aus und wurde mit netbeans erstellt:


Konstruktor:
Java:
public MyFrame() throws IOException {

        
        BufferedImage image = ImageIO.read(new File("C:\\Users\\Bernd\\Desktop\\projekt\\Images\\Background.png"));   
        PictureOnBackground background = new PictureOnBackground(image); /*Regentropfen bild in den Hintergrund bringen*/
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setContentPane(background);

        initComponents();
        jPanel1.setBackground(new Color(1,1,1,100));
        

        jPanelKassabuch.setVisible(false);
        jPanelKassabuch.setBackground(new Color(255,255,255,100));


Mausover von JLabel Kostenstelle & Belegart Verwalten:

MouseMoved:

Java:
private void kostenstelle_belegart_verwaltenMouseMoved(java.awt.event.MouseEvent evt) {                                                           
        
        EventQueue.invokeLater(new Runnable() {

            public void run() {
        kostenstelle_belegart_verwalten.setForeground(Color.red);
        //System.out.println(jPanelKassabuch.getLocation().getX());  /*zum überprüfen ob korrekt positioniert wurde*/
        //System.out.println(jPanelKassabuch.getLocation().getY());
         }
        });

Mouse Exit:


Java:
private void kostenstelle_belegart_verwaltenMouseExited(java.awt.event.MouseEvent evt) {                                                            
        // TODO add your handling code here:

        EventQueue.invokeLater(new Runnable() {

            public void run() {
        kostenstelle_belegart_verwalten.setForeground(Color.BLACK);
        System.out.println(jPanelKassabuch.getLocation().getX());/*zum überprüfen ob korrekt positioniert wurde*/
        System.out.println(jPanelKassabuch.getLocation().getY());


           }
        });




Aufgerufen wird die Animation wenn man auf ein Bild klickt (Bild ist auf meinem Screenshot entfernt worden):

Java:
 private void jLabel3MouseClicked(java.awt.event.MouseEvent evt) {                                     


        jPanelKassabuch.setLocation(-500,-500);
        jPanelKassabuch.setVisible(true);




            new Thread (new Runnable(){
            public void run() {


                System.out.println("2");
                if(istrue==true)
                {
                    int i=100;
                    int j= 810; 
                    for(; i < 240 &&  j > 390; i++, j - =5)
                    {
                        try {
                            Thread.sleep(15);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(MyFrame.class.getName()).log(Level.SEVERE, null, ex);
                        }

                        jPanelKassabuch.setLocation((int)j,(int) i);

                        
                    }

                         istrue=false;


                         Thread.currentThread().stop();



                }

            }



    }).start();

        

    this.repaint();
    SwingUtilities.updateComponentTreeUI(this);
    

        
      

    }


Hoffe mir kann wer helfen 🙂
 
Java:
    public class PictureOnBackground extends JPanel {
    BufferedImage image;
    


    public PictureOnBackground(BufferedImage image) {
        this.image = image;
    }


    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        int w = getWidth();
        int h = getHeight();

        Image scaledImage = image.getScaledInstance(w, h, Image.SCALE_SMOOTH);
        
        
        g.drawImage(image,-820,-360,null);//scaledImage, 0, 0, null);

    }

}
 
OK, das ist anders als erwartet: Da steht das super.paintComponent schon.

BTW: Das
SwingUtilities.updateComponentTreeUI(this);
war wohl nur ein verzweifelter Versucht, den Fehler zu beseitigen, aber das ist falsch, nimm das raus.

Ein Problem könnte noch sein, dass
jPanelKassabuch.setLocation((int)j,(int) i);
von einem eigenen Thread aufgerufen wird, der NICHT der Event-Dispatch-Thread ist. Eigentlich müßte man dieses setLocation mit SwingUtilities auf den EDT legen. Aber Dass er die Schrift so "halbdurchsichtig" anzeigt ist irgendwie suspekt. Vermutlich wäre die Lösung, wie Michael... schon gesagt hat, am schnellsten an einem KSKB zu finden...


EDIT: Da das ja ein Problem zu sein scheint: Irgendwelche Firmenspezifischen Bilder und Texte usw. können natürlich durch Dummy-Bilder ersetzt sein...
 
ja das SwingUtilities.updateComponentTreeUI(this); war ein verzweifelter Versuch. Ich habe es mit x-verschiedenen Updates bzw repaints versucht doch leider erfolglos.


Der Versuch .setlocation im Event-Dispatch-Thread zu lassen bleibt erfolglos. Diese Variante habe ich gestern ebenfalls getestet und es scheint der selbe Fehler auf.

hier der Link mit dem projekt:

File-Upload.net - Java-Forum.zip


Als Hintergrund muss man noch irgend ein bild das bei euch existiert angeben im code
Java:
 public MyFrame() throws IOException {


        
      
        BufferedImage image = ImageIO.read(new File("C:\\xxx\\xxx\\xxx\\xxx\\xxx\\Background.png"));


Fährt mit der Maus dann einfach über alle Labels darüber... aja: erst wenn man auf das Bild drückt startet die Animation

Ich hoffe ihr findet den fehler 🙂
 
Zuletzt bearbeitet:
Ich kann auf das Bild drücken, was ich will, da passiert garnichts.
btw. absolute Pfade zu Dateien anzugeben ist in 99 % sinnlos und in 100 % unschön. Genauso wie direkte Pfadangaben der Klassen. :autsch:
 
Ja, wenn man da rumklickt, erscheinen irgendwann die Labels (nachdem man das mit dem AbsoluteLayout auskommentiert hat - hab' kein NetBeans hier...). Aber wenn man dann über die Labels fährt, passiert nichts (außer dass sie rot werden, und etliche Zahlen ausgegeben werden...)

Bei jedem Neuzeichnen das Bild zu skalieren ist übrigens auch Bogus.

Ich würde dir ja zu sowas raten wie
Java:
class MainPanel extends JPanel
{
    public MainPanel()
    {
        super(new GridLayout(3,1));

        JButton kassa = new JButton("Kassabuch verwalten");
        kassa.addActionListener(...);
        add(kassa);

        JButton kosten = new JButton("Kostenstellen & Belegarten verwalten");
        kosten.addActionListener(...);
        add(kosten);

        JButton bilanz = new JButton("Bilanz ausgeben");
        bilanz.addActionListener(...);
        add(bilanz);
    }
}
Aber Pragmatismus und Zweckmäßigkeit sind wohl out.
 
@Volvagia: ja es gibt elegantere Möglichkeiten mit den Pfaden, das Projekt war auch nur dafür gedacht um euch mein Problem zu erläutern.



@Marco13 : Es wäre eine Möglichkeit einfache Buttons zu haben, doch mein Problem löst dies leider nicht, da ich die Aufgabe habe das Menü grafisch aufzubereiten...


Ich hab jetz einfach mal ein Bildschirm Video gemacht damit ihr seht was ich meine.
Das seltsame an dem Problem ist nur das der Fehler nur auftritt wenn das JPanel transparent gemacht wurde also mit dem 4ten Pharameter (dem Alphawert).

File-Upload.net - Forum.flv
 
Der Alpha-Wert ist der 4te Pharameter zb bei.: jPanelKassabuch.setBackground(new Color(255,255,255,100)); damit wird das Panel transparent. und wenn man diesen 4ten Pharameter wegnimmt und nur sagt jPanelKassabuch.setBackground(new Color(255,255,255)); Funktioniert das Higlighten der Schrift wunderbar nur mit dem Transparenten Panel eben nicht... :autsch:

Kann man vll den Grafik Puffer mal löschen das dies eventuell hilft!?
 
Und warum soll das Panel transparent sein? Natürlich kann man den Hintergrund löschen. Einfach in der paintComponent sowas machen wie
Code:
g.setColor(Color.WHITE);
g.fillRect(0,0,getWidth(),getHeight());
Und bei einem nicht-transparenten Panel wird genau DAS eben in der super.paintComponent gemacht...
 
Der Sinn warum ich alles in einem Panel habe ist, das am Ende nicht nur die 3 Labels im Panel drinnen sein sollen sondern auch noch Bilder. Und ein Panel ist eben doch schneller animiert als X verschiedene Componenten.

Ich werde morgen Früh deinen Code gleich mal ausprobieren, hoffe mit Erfolg 🙂
 
@ Marco: Ich habe deinen Vorschlag jetzt ausprobiert doch leider mit keinem erfolg 🙁

Es passiert folgendes: Es wird wie du schon gesagt hast durchsichtig, da ja das gleiche passiert wie bei dem setBackground mit 4 Pharametern. Doch das Problem bleibt das selbe, die Schrift wird dabei noch undeutlicher "verschmiert"

Java:
jPanelKassabuch = new javax.swing.JPanel(){

    @Override
    public void paintComponent(Graphics g)
    {
        g.setColor(Color.blue);  
        g.fillRect(0,0,0,0);//getWidth(),getHeight());  // kein get Whidth() und auch kein getHeight() sonder 0 da ja sonst das Fenster mit Farbe ausgefüllt wird!
}
}
;
 
Also nun ist der Fehler gelöst, keine Ahnung warum es so funktioniert aber wenn man bei jedem Label folgendes macht wie bei diesem hier funktioniert alles :toll:


Java:
private void kostenstelle_belegart_verwaltenMouseMoved(java.awt.event.MouseEvent evt) {                                                           
        // TODO add your handling code here:
        EventQueue.invokeLater(new Runnable() {

            public void run() {

                for(int i=0;i<20;i++){
                    kostenstelle_belegart_verwalten.setForeground(Color.black);
                    kostenstelle_belegart_verwalten.setForeground(Color.red);
                    repaint();
                }
        System.out.println(jPanelKassabuch.getLocation().getX());
        System.out.println(jPanelKassabuch.getLocation().getY());
         }
        });
}
 
Das funktioniert vielleicht jetzt bei dir, ist aber gröbster (!) Unfug, und auf einem anderen PC funktioniert es vielleicht (!) nicht mehr.
 
Es ist vll nicht die schönste Lösung aber wenn es funktioniert warum nicht? 😉
Eine andere Lösung findet leider niemand... 😳

Kannst mir ja auch gerne sagen was mein Fehler ist :bae:

Wär dir sehr dankbar 🙂


Und das Projekt läuft auf 3 PC's jetzt ohne Probleme mit dieser "Lösung"
 
Bei einigen hundert Zeilen GUI-Builder-generiertem Code macht die Suche nach einem Fehler, den man selbst nicht mal sieht(!) auch noch weniger Spaß also sowieso schon. Wenn du mit der Lösung zufrieden bist, werde ich keine Zeit mehr da rein investieren. Wenn man (nicht mal "professionelle" sondern nur) höhere Ansprüche hätte würde man das ganze sauber und von Hand schreiben, aber wenn es nur darum geht, eine trashig-hackige Lösung auf den ersten Blick schön aussehen zu lassen, wird das wohl OK sein.
 
Ich bin mit dem zwar nicht zufrieden( is auch klar das sieht ja jeder das das eine unsaubere Notlösung ist) nur es ist besser als nichts und es ist zumindest eine Übergangslösung. Ich schätze auch das der Fehler von Java ist und nicht ein eigen Fehler...
Ich werde mich einfach mal an Oracle wenden und weiter hoffen auf eine saubere Lösung.
Da dieses Programm für einen Verein ist, wird es wohl noch für eine gratis Software zu verschmerzen sein, wenn diese einen kleinen Oberflächen fehler hat. Mein Programmier Prof. hat sich ebenfalls den Fehler angesehen und war auch der Meinung, dass es ein Problem von Java sein wird. Hoffe also Oracle wird mir irgendwie weiterhelfen 🙂
 

Neue Themen


Zurück
Oben