JFrame无法正确绘制

时间:2015-06-21 01:37:16

标签: java swing jframe

我想要一个简单的程序,用滑块改变矩形的宽度。 当我运行它时,jpanel无法正常工作,因为它只适合panel.width宽度,并且它没有正确重新绘制。

import java.awt.*;
import javax.swing.*;

public class panel extends JPanel {

    private int width = 50;

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.GRAY);
        g.fillRect(20, 20, width, 25);
    }

    public void setWidth(int width) {
        this.width = (width > 0) ? width : 0;
        repaint();
    }

    public int getWidth() {
        return width;
    }
}

GUI:

import java.awt.*;

import javax.swing.*;
import javax.swing.event.*;

public class Gui extends JFrame {

    private panel p;
    private JSlider slider;

    Gui() {
        super("Draw program");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        p = new panel();
        p.setBackground(Color.RED);
        slider = new JSlider(SwingConstants.HORIZONTAL, 0, 300, p.getWidth());
        slider.setMajorTickSpacing(50);
        slider.setPaintTicks(true);
        add(p);
        add(slider, BorderLayout.SOUTH);
        slider.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                p.setWidth(slider.getValue());
            }
        });
    }
}

1 个答案:

答案 0 :(得分:5)

您的面板类会覆盖Component类的一个键方法(JPanel继承自它):getWidth。

这个问题是Swing布局管理器可能会使用此方法中的值来调整组件的大小。

解决方案:更改方法名称。

如,

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class Gui extends JFrame {

   private MyPanel p;
   private JSlider slider;

   Gui() {
      super("Draw program");
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      p = new MyPanel();
      p.setBackground(Color.RED);
      slider = new JSlider(SwingConstants.HORIZONTAL, 0, MyPanel.GRAY_MAX_LENGTH, p.getGrayWidth());
      slider.setMajorTickSpacing(50);
      slider.setPaintTicks(true);
      add(p);
      add(slider, BorderLayout.SOUTH);
      slider.addChangeListener(new ChangeListener() {
         public void stateChanged(ChangeEvent e) {
            p.setGrayWidth(slider.getValue());
         }
      });
   }

   // so we can test our code
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            Gui gui = new Gui();
            gui.pack();
            gui.setLocationRelativeTo(null);
            gui.setVisible(true);
         }
      });
   }
}

// note that this class should not be named
// panel as class names should start with an upper-case letter
class MyPanel extends JPanel {
   // constants to avoid use of "magic" numbers
   public static final int GRAY_MAX_LENGTH = 300;
   private static final int RECT_HEIGHT = 25;
   private static final int GAP = 20;
   private static final int PREF_W = GRAY_MAX_LENGTH + 2 * GAP;
   private static final int PREF_H = RECT_HEIGHT + 2 * GAP;
   private int grayWidth = 50;

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(Color.GRAY);
      g.fillRect(GAP, GAP, grayWidth, RECT_HEIGHT);
   }

   @Override // so our GUI is big enough
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   public void setGrayWidth(int width) {
      this.grayWidth = (width > 0) ? width : 0;
      repaint();
   }

   // ***** key is to change this method's name so you don't
   // override JPanel's getWidth() method
   public int getGrayWidth() {
      return grayWidth;
   }
}