Hintergrundfarbe

Drucker

Mitglied
Hallo!
arbeite gerade an einem kleinem Graphik-Programm.
Leider funktioniert eine Funktion nicht wie gewünscht.

Ich möchte die Hintergrundfarbe ändern, so bald ich "Hintergrundfarbe" ausgewählt habe.
Ich verstehe nicht, warum das beim ersten Mal nicht funktioniert.

Kann mir jemand helfen?

Hier der Code:
Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Drucker_01_1 extends JFrame {
    public static void main(String[] args){
        new Drucker_01_1();
    }

    public Drucker_01_1() {
        setSize(600, 450);
        setTitle("Druckers Uebung");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        MyJPanel panel= new MyJPanel();
        Container c = getContentPane();
        c.add(panel);
        setVisible(true);
    }

    public class MyJPanel extends JPanel implements ActionListener, MouseListener, MouseMotionListener {

    JRadioButton button1, button2, button3;
    ButtonGroup group;
    JSlider sliderR, sliderG, sliderB, sliderPen;
    JLabel labelR, labelG, labelB, labelPen;
        JButton button;
        int colorR, colorG, colorB;
        int rad, x = -100, y = -100;
    int x1, x2, y1, y2;
    boolean isButtonClicked = false;
  
        public MyJPanel() {
       setLayout(null);

            addMouseListener(this);
       addMouseMotionListener(this);

       button1 = new JRadioButton("Linie", true);
       button1.setBounds(300, 45, 100, 30);
       button1.addActionListener(this);

       button2 = new JRadioButton("handschriftlich", false);
       button2.setBounds(420, 45, 200, 30);
       button2.addActionListener(this);

       button3 = new JRadioButton("Hintergrundfarbe", false);
       button3.setBounds(40, 85, 150, 30);
       button3.addActionListener(this);

       labelR = new JLabel("rot");
       labelR.setBounds(40, 10, 20, 25);
       sliderR = new JSlider(0, 255, 0);
       sliderR.setBounds(60, 10, 200, 25);
       sliderR.setMajorTickSpacing(25);
       sliderR.setPaintTicks(true);

       labelG = new JLabel("gruen");
       labelG.setBounds(40, 35, 20, 25);
       sliderG = new JSlider(0, 255, 0);
       sliderG.setBounds(60, 35, 200, 25);
       sliderG.setMajorTickSpacing(25);
       sliderG.setPaintTicks(true);

       labelB = new JLabel("blau");
       labelB.setBounds(40, 60, 20, 25);
       sliderB = new JSlider(0, 255, 0);
       sliderB.setBounds(60, 60, 200, 25);
       sliderB.setMajorTickSpacing(25);
       sliderB.setPaintTicks(true);

       labelPen = new JLabel("Dicke");
       labelPen.setBounds(280, 10, 100, 25);
       sliderPen = new JSlider(2, 50, 25);
       sliderPen.setBounds(360, 10, 200, 25);
       sliderPen.setMajorTickSpacing(5);
       sliderPen.setPaintTicks(true);

       button = new JButton("Loeschen");
       button.setBounds(410, 90, 100, 30);
       button.addActionListener(this);

       group = new ButtonGroup();
       group.add(button1);
       group.add(button2);
      
       add(labelR);
       add(sliderR);
       add(labelG);
       add(sliderG);
       add(labelB);
       add(sliderB);
       add(labelPen);
       add(sliderPen);
       add(button);
       add(button1);
       add(button2);
       add(button3);
    }

    public void paintComponent(Graphics g) {
     if (isButtonClicked) {
       super.paintComponent(g);
       isButtonClicked = false;
     }
                
     if(button3.isSelected()){
                
         setBackground(new Color(colorR, colorG, colorB));
         g.setColor(Color.white);
        
         if(button2.isSelected()){
         g.fillOval(x-rad/2, y-rad/2, rad, rad);
         }else {
         g.drawLine(x1, y1, x2, y2);
         }
     } else {
        g.setColor(new Color(colorR, colorG, colorB));
        if(button2.isSelected()){
             g.fillOval(x-rad/2, y-rad/2, rad, rad);
            }else {
            g.drawLine(x1, y1, x2, y2);
            }
       }
       repaint();
        }

        public void actionPerformed(ActionEvent e) {
            isButtonClicked = true;
       repaint();
        }

        public void mouseClicked(MouseEvent e) {
        }

        public void mousePressed(MouseEvent e) {
       x1 = e.getX();
       y1 = e.getY();
        }

        public void mouseReleased(MouseEvent e) {
            x = -100;
       y = -100;
       x2 = e.getX();
       y2 = e.getY();
       repaint();
        }

        public void mouseExited(MouseEvent e) {
        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseMoved(MouseEvent e) {
        }

        public void mouseDragged(MouseEvent e) {
       colorR = sliderR.getValue();
       colorG = sliderG.getValue();
       colorB = sliderB.getValue();
       rad = sliderPen.getValue();           
       x = e.getX();
       y = e.getY();
       repaint();
        }
    }
}
 
Zuletzt bearbeitet von einem Moderator:

Enceladus271

Bekanntes Mitglied
1. Durch das repaint am Ende der paintComponent erzeugst du eine Endlosschleife. Meine CPU Last geht von 0% auf 44% hoch wenn das Programm läuft. Wenn die paintComponent abgearbeitet wurde ist ja alles auf dem aktuellen Stand. Also erstmal raus mit dem repaint.

2. Wenn du auf einem Panel Komponenten liegen hast und paintComponent überschreibst, sollte immer super.paintComponent aufgerufen werden.

3. paintComponent wird immer wieder automatisch aufgerufen (es reicht schon einmal irgendwo auf das Panel zu klicken). Das solltest du bedenken wenn du in dieser Methode Instanzvariablen änderst.

4. Beim nächsten mal bitte die Javacode Tags verwenden wenn du Code postest:
[code = Java ] (ohne Leerzeichen)
...
[/code]
 

Drucker

Mitglied
Hallo Enceladus271, ganz herzlichen Dank für Deine Hilfe!
Leider bin ich ziemlicher Anfänger und konnte trotz deine Hinweise nicht so gut verstehen, welche Code ich korrigieren sollte, damit ich wenn ich "Hintergrundfarbe" auswähle sofort die Hintergrundfarbe ändern kann ohne "Loeschen" geklickt zu haben.
Sorry für mein unglaubliches Anfänger-Niveau...
1. wenn ich "repaint" rausgenommen habe, dann wurde der Titel "Hintergrundfarbe" doppelt gezeigt, also habe ich es wieder reingeschrieben.
2. Welche Panel Komponenten sollte ich mit paintComponent überschreiben?
3. Wie soll ich die Methode PaintComponent ändern?

Grüße und nochmal vielen Dank.
 

Enceladus271

Bekanntes Mitglied
So sollte es funktionieren:
Java:
    @Override
     public void paintComponent( Graphics g ) {
       super.paintComponent( g ); // <- Das hier immer ausführen

       if ( button3.isSelected() ) {
         setBackground( new Color( colorR, colorG, colorB ) );
         g.setColor( Color.white );
         if ( button2.isSelected() ) {
           g.fillOval( x - rad / 2, y - rad / 2, rad, rad );
         } else {
           g.drawLine( x1, y1, x2, y2 );
         }
       } else {
         setBackground( new JPanel().getBackground() ); // Hintergrund wieder auf Standard setzen
         g.setColor( new Color( colorR, colorG, colorB ) );
         if ( button2.isSelected() ) {
           g.fillOval( x - rad / 2, y - rad / 2, rad, rad );
         } else {
           g.drawLine( x1, y1, x2, y2 );
         }
       }
       // repaint(); // <- Das hier raus, da repaint wieder paintComponent aufruft
     }
 

Drucker

Mitglied
Hallo Enceladus271,
herzlichen Dank für deine Mühe!

Mit Deinem Code funktioniert das Programm schon besser, allerdings kann nun keine Linie mehr gezogen werden. Also entweder die Hintergrundfarbe läßt sich ändern, dann kann man eben keine Linie mehr ziehen, oder man kann Linien ziehen, aber mit der Hintergrundfarbe gibt es Probleme.

Wenn ich das Repaint() auskommentiere, dann bleiben Kreise (Punkte) auch nicht dauerhaft stehen, sondern nur der letzte Kreis (Punkt) ist sichtbar.

Also: Wenn Du nochmal Lust hast Dir die Sache anzuschauen, ich habe jetzt nochmal sehr lange herumprobiert, und verzweifele langsam ...

Allerbeste Grüße :)
 

Enceladus271

Bekanntes Mitglied
OK, ich hab nicht gesehen, dass das ein Zeichenprogramm werden soll. Du hast folgendes Problem:

1. Die Farbe die du mit setBackground setzt wird nur gezeichnet wenn in paintComponent super.paintComponent aufgerufen wird. Daher brauchst du immer das super.paintComponent

2. super.paintComponent zeichnet aber über alles bisher gezeichnete drüber. Löscht also alles.

Du könntest das Problem lösen, indem du eine Liste von Zeichenobjekten anlegst und immer alles zeichnest. Ich hab mal einen ersten Ansatz in deinen Code eingebaut:

Java:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;

public class Zeichenobjekt {

   private final Shape   shape;
   private final Color   color;

   public Zeichenobjekt( Shape shape, Color color ) {
     super();
     this.shape = shape;
     this.color = color;
   }

   public void draw( Graphics2D g ) {
     g.setColor( color );
     g.draw( shape );
   }
}

Java:
public class Drucker_01_1 extends JFrame {

   public static void main( String[] args ) {
     new Drucker_01_1();
   }

   public Drucker_01_1() {
     setSize( 600, 450 );
     setTitle( "Druckers Uebung" );
     setDefaultCloseOperation( EXIT_ON_CLOSE );

     MyJPanel panel = new MyJPanel();
     Container c = getContentPane();
     c.add( panel );
     setVisible( true );
   }

   public class MyJPanel extends JPanel implements ActionListener, MouseListener, MouseMotionListener {

     JRadioButton                       button1, button2;
     ButtonGroup                         group;
     JSlider                             sliderR, sliderG, sliderB, sliderPen;
     JLabel                             labelR, labelG, labelB, labelPen;
     JButton                             button;
     JButton                             button3;
     int                                 colorR, colorG, colorB;
     int                                 rad, x = -100, y = -100;
     int                                 x1, x2, y1, y2;

     private final List<Zeichenobjekt>   zeichenobjekte   = new ArrayList<>();

     public MyJPanel() {
       setLayout( null );

       addMouseListener( this );
       addMouseMotionListener( this );

       button1 = new JRadioButton( "Linie", true );
       button1.setBounds( 300, 45, 100, 30 );
       button1.addActionListener( this );

       button2 = new JRadioButton( "handschriftlich", false );
       button2.setBounds( 420, 45, 200, 30 );
       button2.addActionListener( this );

       button3 = new JButton( "Hintergrundfarbe" );
       button3.setBounds( 40, 85, 150, 30 );
       button3.addActionListener( this );

       labelR = new JLabel( "rot" );
       labelR.setBounds( 40, 10, 20, 25 );
       sliderR = new JSlider( 0, 255, 0 );
       sliderR.setBounds( 60, 10, 200, 25 );
       sliderR.setMajorTickSpacing( 25 );
       sliderR.setPaintTicks( true );

       labelG = new JLabel( "gruen" );
       labelG.setBounds( 40, 35, 20, 25 );
       sliderG = new JSlider( 0, 255, 0 );
       sliderG.setBounds( 60, 35, 200, 25 );
       sliderG.setMajorTickSpacing( 25 );
       sliderG.setPaintTicks( true );

       labelB = new JLabel( "blau" );
       labelB.setBounds( 40, 60, 20, 25 );
       sliderB = new JSlider( 0, 255, 0 );
       sliderB.setBounds( 60, 60, 200, 25 );
       sliderB.setMajorTickSpacing( 25 );
       sliderB.setPaintTicks( true );

       labelPen = new JLabel( "Dicke" );
       labelPen.setBounds( 280, 10, 100, 25 );
       sliderPen = new JSlider( 2, 50, 25 );
       sliderPen.setBounds( 360, 10, 200, 25 );
       sliderPen.setMajorTickSpacing( 5 );
       sliderPen.setPaintTicks( true );

       button = new JButton( "Loeschen" );
       button.setBounds( 410, 90, 100, 30 );
       button.addActionListener( this );

       group = new ButtonGroup();
       group.add( button1 );
       group.add( button2 );

       add( labelR );
       add( sliderR );
       add( labelG );
       add( sliderG );
       add( labelB );
       add( sliderB );
       add( labelPen );
       add( sliderPen );
       add( button );
       add( button1 );
       add( button2 );
       add( button3 );
     }

     @Override
     public void paintComponent( Graphics g ) {
       super.paintComponent( g );
       final Graphics2D g2d = (Graphics2D) g;
       for ( Zeichenobjekt zeichenobjekt : zeichenobjekte ) {
         zeichenobjekt.draw( g2d );
       }
     }

     @Override
     public void actionPerformed( ActionEvent e ) {
       if ( e.getSource() == button3 ) {
         colorR = sliderR.getValue();
         colorG = sliderG.getValue();
         colorB = sliderB.getValue();
         setBackground( new Color( colorR, colorG, colorB ) );
         repaint();
       }
     }

     @Override
     public void mouseClicked( MouseEvent e ) {}

     @Override
     public void mousePressed( MouseEvent e ) {
       x1 = e.getX();
       y1 = e.getY();
     }

     @Override
     public void mouseReleased( MouseEvent e ) {
       x = -100;
       y = -100;
       x2 = e.getX();
       y2 = e.getY();
       zeichenobjekte.add( new Zeichenobjekt( new Line2D.Double( x1, y1, x2, y2 ), getColor() ) );
       repaint();
     }

     @Override
     public void mouseExited( MouseEvent e ) {}

     @Override
     public void mouseEntered( MouseEvent e ) {}

     @Override
     public void mouseMoved( MouseEvent e ) {}

     @Override
     public void mouseDragged( MouseEvent e ) {
       colorR = sliderR.getValue();
       colorG = sliderG.getValue();
       colorB = sliderB.getValue();
       rad = sliderPen.getValue();
       x = e.getX();
       y = e.getY();
       repaint();
     }

     private Color getColor() {
       colorR = sliderR.getValue();
       colorG = sliderG.getValue();
       colorB = sliderB.getValue();
       return new Color( colorR, colorG, colorB );
     }
   }
}

Funktioniert erstmal nur für Linien. Aber nach diesem Prinzip kannst du auch andere Objekte zeichnen. Das hätte sogar den großen Vorteil, dass du später noch einen "Rückgängig" Button einbauen kannst. Der müsste dann nur aus der Liste das letzte Element entfernen.
 

Drucker

Mitglied
Hallo Enceladus271, erstmal ganz herzlichen Dank für die Hilfe und die Mühen. Melde mich erst jetzt weil ich das alles erstmal verdauen musste. Habe auch sehr viel gelernt und verdammt viele Stunden mit Deinem Code zugebracht. Hoffe das ich das eines Tages so wie Du aus dem Ärmel schütteln kann! Danke nochmal,
Drucker
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Swing JTable cellRenderer mit jpg Hintergrundfarbe lässt sich nicht ändern. AWT, Swing, JavaFX & SWT 1
E Hintergrundfarbe setzen in JPanel funktioneirt nicht AWT, Swing, JavaFX & SWT 4
E JavaFX SplitMenuButton Hintergrundfarbe AWT, Swing, JavaFX & SWT 1
E Swing Miserable Performance beim Ändern der Hintergrundfarbe von JLabels AWT, Swing, JavaFX & SWT 3
C JavaFx TabelView - hintergrundfarbe möglich? AWT, Swing, JavaFX & SWT 1
S Swing Probleme mit transparenz der Hintergrundfarbe und JRadioButtons AWT, Swing, JavaFX & SWT 2
M JavaFX MenuItem Hintergrundfarbe in CSS AWT, Swing, JavaFX & SWT 4
A JButtons - es wird beim falschen Button die Hintergrundfarbe angepasst AWT, Swing, JavaFX & SWT 2
C Swing Hintergrundfarbe von Submenüeinträgen setzen AWT, Swing, JavaFX & SWT 2
M JComboBox Hintergrundfarbe des gewählten Items AWT, Swing, JavaFX & SWT 3
S Swing Hintergrundfarbe ändern AWT, Swing, JavaFX & SWT 9
R Swing Hintergrundfarbe der Zelle in einer JTable bei Markierung AWT, Swing, JavaFX & SWT 2
K Hintergrundfarbe des Frames ändern AWT, Swing, JavaFX & SWT 4
M Swing JTree: Wie kann ich die Hintergrundfarbe der selection ändern?!?! AWT, Swing, JavaFX & SWT 7
W Swing Hintergrundfarbe ändern AWT, Swing, JavaFX & SWT 4
S JTable Hintergrundfarbe AWT, Swing, JavaFX & SWT 5
M Hover-Farbe über Hintergrundfarbe legen AWT, Swing, JavaFX & SWT 3
B Hintergrundfarbe der JComboBox AWT, Swing, JavaFX & SWT 3
Shanks Hintergrundfarbe durch Button click ändern ?? AWT, Swing, JavaFX & SWT 6
A Hintergrundfarbe eines Applets ändern AWT, Swing, JavaFX & SWT 2
Psypsy Swing Jpanel Hintergrundfarbe ändern AWT, Swing, JavaFX & SWT 10
E Hintergrundfarbe wird nicht angezeigt AWT, Swing, JavaFX & SWT 2
S Hintergrundfarbe in JToolbar nicht angezeigt AWT, Swing, JavaFX & SWT 2
P Swing Hintergrundfarbe auslesen und wieder setzen AWT, Swing, JavaFX & SWT 4
J Hintergrundfarbe von CheckBoxen in einer JTable AWT, Swing, JavaFX & SWT 4
E Swing JComboBox Hintergrundfarbe AWT, Swing, JavaFX & SWT 6
R Hintergrundfarbe vom Fenster AWT, Swing, JavaFX & SWT 2
M Hintergrundfarbe ändern AWT, Swing, JavaFX & SWT 5
M AWT Hintergrundfarbe zuweisen AWT, Swing, JavaFX & SWT 6
T einzelne Zelle einer JTable auswählen und Hintergrundfarbe ändern AWT, Swing, JavaFX & SWT 2
calzone JTable und Hintergrundfarbe AWT, Swing, JavaFX & SWT 12
G Hintergrundfarbe eines JPanels zurücksetzen AWT, Swing, JavaFX & SWT 12
G JToggleButton - Hintergrundfarbe beim Drücken festlegen AWT, Swing, JavaFX & SWT 4
S Hintergrundfarbe in einer Spalte der JTable verändern AWT, Swing, JavaFX & SWT 3
G JTextArea - Hintergrundfarbe? AWT, Swing, JavaFX & SWT 5
hdi Hintergrundfarbe von Label AWT, Swing, JavaFX & SWT 2
T Warum nehmen diese Labels die Hintergrundfarbe nicht an? AWT, Swing, JavaFX & SWT 6
D Browser -> Hintergrundfarbe AWT, Swing, JavaFX & SWT 11
T jtree Hintergrundfarbe für ganze Zeile AWT, Swing, JavaFX & SWT 2
S Hintergrundfarbe eines JFrames ändern AWT, Swing, JavaFX & SWT 2
C Hintergrundfarbe von einem disabled Button ändern ? AWT, Swing, JavaFX & SWT 7
R JTable Hintergrundfarbe ändern AWT, Swing, JavaFX & SWT 7
foobar Hintergrundfarbe eines JMenus ändern AWT, Swing, JavaFX & SWT 2
O Hintergrundfarbe beim ToolTip AWT, Swing, JavaFX & SWT 5
J [Newbie] Hintergrundfarbe ändern AWT, Swing, JavaFX & SWT 2
J JTabbedPane Hintergrundfarbe Problem AWT, Swing, JavaFX & SWT 8
S Hintergrundfarbe für JFrame AWT, Swing, JavaFX & SWT 6
I Hintergrundfarbe beim JLabel AWT, Swing, JavaFX & SWT 3
G JList: Hintergrundfarbe eines Eintrags AWT, Swing, JavaFX & SWT 5

Ähnliche Java Themen

Neue Themen


Oben