简体   繁体   中英

How to repaint() a StrokePanel in java

I'm trying to make the figure change everytime i press one of the four buttons. The figure does change everytime i run the file but i don't know how to change it when i press the buttons.
Is there a method i can call to repaint the StrokePanel or do i have to do something else?

This is the code so far

 import java.awt.*;   
 import java.awt.event.*;
 import javax.swing.*;
 import java.awt.geom.*;
 import javax.swing.border.LineBorder;

 public class GeomtryQuiz extends JApplet{

  boolean playing = true;
  static int chosen = 0;
  static boolean answer = false;
  static boolean change = false;


  public static void main(String[] args){

   JFrame frame = new JFrame();
   frame.setTitle("Geometry Quiz");
   frame.setSize(1024,900);
   frame.setBackground(Color.white);

   JApplet applet = new GeomtryQuiz();
   applet.init();
   JButton[] buttons = new JButton[4];
   buttons[0] = new JButton("Triangle");
   buttons[1] = new JButton("Square");
   buttons[2] = new JButton("Pentagon");
   buttons[3] = new JButton("Hexagon");
   frame.getContentPane().add(applet);

   Container c =  frame.getContentPane();
   JPanel p = new JPanel(); 
   p.setLayout(new GridLayout(2,2));
   c.setLayout(new BorderLayout());

   for(int i = 0 ; i < 4; i++){
      buttons[i].setPreferredSize(new Dimension(70,70));
      buttons[i].setBackground(Color.pink);
      final JButton b = buttons[i];
      final int angle = i;
      final int n = 3;

      b.addActionListener(

         new ActionListener(){

            public void actionPerformed(ActionEvent e){
               if(b.isEnabled()){
                  control(angle);  
               }
               if(!b.isEnabled()){
               }
            }
         }
         );  

      p.add(buttons[i]);
   }
   c.add(p,BorderLayout.SOUTH);
   c.add(applet,BorderLayout.CENTER);
   frame.setVisible(true);
}

public static void control(int i){
   if((i + 3) == chosen){
      JOptionPane.showMessageDialog(null,"Correct");


   }
   else{
      JOptionPane.showMessageDialog(null,"Wrong");

   }
     change = true;
}

public void init() {
   JPanel panel = new StrokePanel();
   getContentPane().add(panel);
}


class StrokePanel extends JPanel {

  public StrokePanel() {
     setPreferredSize(new Dimension(1024,800));
     setBackground(Color.white);
  }
  public void paintComponent(Graphics f){

     Graphics2D g = (Graphics2D)f;
     Point2D center = new Point2D.Float(512,250);
     float radius = 1000;
     float[] dist = {0.1f, 0.2f, 1.0f};
     Color[] colors1 = {Color.white, Color.white, Color.red};
     RadialGradientPaint p = new RadialGradientPaint(center, radius, dist, colors1);

     g.setPaint(p);
     g.fillRect(0,0,1024,800);
     int random = (int)(Math.random()*4 + 3);

     chosen = random;       
     drawShape(g,random);        

           }
  public void drawShape(Graphics g,int numri_brinjeve)
  {


     Graphics2D  g2 = (Graphics2D)g;
     g2.setStroke(new BasicStroke(2.0f));
     g.setColor(Color.pink);
     g2.translate(512,250);      
     double kendi = 360.0/numri_brinjeve;
     GeneralPath path = new GeneralPath();
     double a = 0;
     double c = 0;
     double x = 0;
     double y = 0;
     double r = 150;

     for(int i = 1 ;  i <= numri_brinjeve + 1 ;  i++) {

        x = r* Math.cos(Math.toRadians(i*kendi));
        y = r* Math.sin(Math.toRadians(i*kendi));

        a = x;
        c = -y;
        if(i == 1)
           path.moveTo(a, c);

       // System.out.println(i + ", " + a + ", " + c + "," + i*kendi);
        path.lineTo(a, c);
     }

     g2.fill(path);
     g2.setColor(Color.lightGray);
     Stroke stroke = new BasicStroke(7);
     g2.setStroke(stroke);
     g2.draw(path);
  }  
 }
}

I'm trying to make the figure change everytime i press one of the four buttons

You need to call repaint to trigger a new paint cycle

Observations...

extends JApplet is confusing matters. As a general rule, you should not be creating and manipulating an Applet yourself, they are meant to be managed by the browser plugin.

Based on you code, I can't see any real reason to have it all, so I'd start by getting rid of it.

Now, this will begin to create additional issues, which highlights over problems you were probably having

//JApplet applet = new GeomtryQuiz();
//applet.init();

frame.getContentPane().add(applet);
//...
c.add(p, BorderLayout.SOUTH);
c.add(applet, BorderLayout.CENTER);

Okay, so you first add the applet to the content pane, but then add it again later ...? In this case, this is actually a no-operation, but could have caused no end of issues, make sure you're only adding the component once

But this raises the next question of, what to use instead of the applet? Well, since the only thing the applet was doing was adding the StrokePanel to it, then it's simple, just use the StrokePanel instead

This is where things get a little more complicated.

Basically, the StrokePanel needs to maintain it's current state, so chosen should actually be a property of the StrokePanel , also, chosen should not be modified from within the paintComponent , this will cause no end of issues, as paintComponent can be called for any number reasons at any time, mostly without your involvement. So, instead, you'll need some way to set and get that value

StrokePanel

class StrokePanel extends JPanel {

    private int chosen = 0;

    public StrokePanel() {
        setPreferredSize(new Dimension(1024, 800));
        setBackground(Color.white);
    }

    public int getChosen() {
        return chosen;
    }

    public void setChosen(int chosen) {
        this.chosen = chosen;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics f) {
        super.paintComponent(f);
        Graphics2D g = (Graphics2D) f;
        Point2D center = new Point2D.Float(512, 250);
        float radius = 1000;
        float[] dist = {0.1f, 0.2f, 1.0f};
        Color[] colors1 = {Color.white, Color.white, Color.red};
        RadialGradientPaint p = new RadialGradientPaint(center, radius, dist, colors1);

        g.setPaint(p);
        g.fillRect(0, 0, 1024, 800);
        drawShape(g, getChosen());

    }

    public void drawShape(Graphics g, int numri_brinjeve) {

        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(2.0f));
        g.setColor(Color.pink);
        g2.translate(512, 250);
        double kendi = 360.0 / numri_brinjeve;
        GeneralPath path = new GeneralPath();
        double a = 0;
        double c = 0;
        double x = 0;
        double y = 0;
        double r = 150;

        for (int i = 1; i <= numri_brinjeve + 1; i++) {

            x = r * Math.cos(Math.toRadians(i * kendi));
            y = r * Math.sin(Math.toRadians(i * kendi));

            a = x;
            c = -y;
            if (i == 1) {
                path.moveTo(a, c);
            }

            // System.out.println(i + ", " + a + ", " + c + "," + i*kendi);
            path.lineTo(a, c);
        }

        g2.fill(path);
        g2.setColor(Color.lightGray);
        Stroke stroke = new BasicStroke(7);
        g2.setStroke(stroke);
        g2.draw(path);
    }
}

GeomtryQuiz

I've not a little bit of re-work on this, mainly, I've removed the JApplet and moved the core application out of a static context (pet hate).

The major update is the inclusion of an update method, which generates the random shape and updates the StrokePanel

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class GeomtryQuiz {

    boolean playing = true;
    boolean answer = false;
    boolean change = false;

    private StrokePanel strokePanel;

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

    public GeomtryQuiz() {

        JFrame frame = new JFrame();
        frame.setTitle("Geometry Quiz");
        frame.setSize(1024, 900);
        frame.setBackground(Color.white);

        JButton[] buttons = new JButton[4];
        buttons[0] = new JButton("Triangle");
        buttons[1] = new JButton("Square");
        buttons[2] = new JButton("Pentagon");
        buttons[3] = new JButton("Hexagon");

        Container c = frame.getContentPane();
        JPanel p = new JPanel();
        p.setLayout(new GridLayout(2, 2));

        for (int i = 0; i < 4; i++) {
            buttons[i].setPreferredSize(new Dimension(70, 70));
            buttons[i].setBackground(Color.pink);
            final JButton b = buttons[i];
            final int angle = i;
            final int n = 3;

            b.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (b.isEnabled()) {
                        control(angle);
                    }
                    if (!b.isEnabled()) {
                    }
                }
            });

            p.add(buttons[i]);
        }
        c.add(p, BorderLayout.SOUTH);

        strokePanel = new StrokePanel();
        c.add(strokePanel, BorderLayout.CENTER);
        update();
        frame.setVisible(true);
    }

    protected void update() {
        int last = strokePanel.getShape();
        int random = last;
        do {
            random = (int) (Math.random() * 4 + 3);
        } while (random != last);
        strokePanel.setShape(random);
    }

    public void control(int i) {
        if ((i + 3) == strokePanel.getShape()) {
            JOptionPane.showMessageDialog(null, "Correct");
            update();
        } else {
            JOptionPane.showMessageDialog(null, "Wrong");

        }
        change = true;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM