Java-Swing组件的问题

Java-Swing组件的问题,java,swing,paintcomponent,Java,Swing,Paintcomponent,我正在尝试编写一个swing gui,通过按两个不同的项目,圆形和矩形,我可以在任意位置绘制形状。 我让它工作,但我用 Graphics2D gg = (Graphics2D) canvas.getGraphics(); 有人建议我使用并覆盖paintComponent()。所以我几个小时前就开始尝试了:D 我知道有很多关于这方面的问题,但我确实读了很多,尝试了很多,搜索了很多,但我还是忍不住 请看一下我的RandomDrawer类,我发现我必须在那里实现paintComponent()(我希

我正在尝试编写一个swing gui,通过按两个不同的项目,圆形和矩形,我可以在任意位置绘制形状。 我让它工作,但我用

Graphics2D gg = (Graphics2D) canvas.getGraphics();
有人建议我使用并覆盖paintComponent()。所以我几个小时前就开始尝试了:D 我知道有很多关于这方面的问题,但我确实读了很多,尝试了很多,搜索了很多,但我还是忍不住

请看一下我的RandomDrawer类,我发现我必须在那里实现paintComponent()(我希望至少是这样)。 在下一个方法中进一步介绍

public void actionPerformed(ActionEvent e)
我开始知道发生了什么动作,我可以或者怎样告诉他以后画画?还是我的整个方法都有缺陷

这是我的密码

谢谢你对我的容忍,非常感谢

package plotterpackage;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.Random;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
import javax.swing.text.JTextComponent;



public class PlotterApp implements ComponentListener  {
private JFrame frame;
private JPanel canvas;
private JPanel statusBar;
private JTextField status;
/**
 * Public default constructor.    
 */
public PlotterApp() {
    initialize();
}
/**
 * Start of the application.
 * @param args command line arguments
 */
public static void main(String[] args) {
    PlotterApp app = new PlotterApp();
    app.start();
}
/**
 * Initialize the application.
 */
protected void initialize() {
    frame = new JFrame("Main");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setBounds(50,50, 50+640, 50+480);
    frame.setBackground(Color.GREEN);
    frame.setJMenuBar(createMenuBar());

    frame.getContentPane().add(createContent(), BorderLayout.CENTER);
    frame.getContentPane().add(createStatusBar(),BorderLayout.SOUTH);        
}
/**
 * Start the graphical user interface.
 */
public void start() {
    // show the GUI
    frame.setVisible(true);
    status.setText("Application started");
}
/**-*
 * Internal helper to create the main content.
 * @return component with application content.
 */
protected JComponent createContent() {
    canvas = new JPanel();
    canvas.addMouseListener(new Painter());
    canvas.addMouseMotionListener(new Painter());
    canvas.addComponentListener(this);
    canvas.setBackground(new Color(128,218,255));
    canvas.setForeground(Color.RED);
    canvas.setBorder(new BevelBorder(BevelBorder.LOWERED));
    return canvas;
}
/**
 * Internal helper to create the statusbar and -fields.
 * @return component with status/bar.
 */    
protected JComponent createStatusBar() {
    FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
    layout.setHgap(5);

    statusBar = new JPanel(layout);
    statusBar.add(new JLabel("Status: "));

    status = new JTextField();
    status.setPreferredSize(new Dimension(400,25));
    status.setEditable(false);
status.setBorder(newBevelBorder(BevelBorder.RAISED,Color.MAGENTA,Color.LIGHT_GRAY));
    status.getInsets().set(2, 10, 2, 10);
    statusBar.add(status);

    return statusBar;
}
/**
 * Internal helper to create the frames menubar.
 * @return menu bar 
 */
protected JMenuBar createMenuBar() {
    JMenuBar mb = new JMenuBar();
    JMenuItem item;
    JMenu menu;
    // Action menu
    menu = new JMenu("Actions");
    mb.add(menu);
    item = new JMenuItem("Draw RandomCircle");
    item.addActionListener(new RandomDrawer());
    menu.add(item);

    item = new JMenuItem("Draw RandomRectangle");
    item.addActionListener(new RandomDrawer());
    menu.add(item);

    menu.addSeparator();
    item = new JMenuItem("Exit");
    item.addActionListener(new AppCloser());
    menu.add(item);

    // Color menu not used so far
    menu = new JMenu("Colors");        
    mb.add(menu);
    // Help menu not used so far
    menu = new JMenu("Help");        
    mb.add(menu);

    return mb;
}

class AppCloser implements ActionListener {
    /* (non-Javadoc)
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("application finished, bye-bye... ");
        frame.setVisible(false);
        frame.dispose();
        System.exit(0);
    }        
}

class RandomDrawer extends JPanel implements ActionListener {
    /* (non-Javadoc)
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */ 
    @Override
    protected void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2 = (Graphics2D) g;
          g2.setColor(Color.BLACK);
          g2.drawOval(100, 100, 100, 100);  
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Random generator = new Random();
        int x = generator.nextInt(100)+100;
        int y = generator.nextInt(100)+100;
        int w;

        if (e.getActionCommand()==("Draw RandomCircle")) {
            System.out.printf("x = %d y = %d\n", x, y);
            //status.setText(String.format("rnd draw x:  y: "));
            //gg.setColor(Color.BLACK);
            //gg.drawOval(x, y, generator.nextInt(x), generator.nextInt(y));    
        }

        else if (e.getActionCommand()==("Draw RandomRectangle")) {
            System.out.printf("x = %d y = %d\n", x, y);
            //status.setText(String.format("rnd draw x:  y: "));
            //Graphics2D gg = (Graphics2D) canvas.getGraphics();
            //gg.setColor(Color.BLACK);
            //gg.drawRect(x, y, generator.nextInt(x), generator.nextInt(y));    
        }
    }
}


class Painter extends MouseAdapter implements MouseMotionListener {

  Point start, end;
  int startX, startY, oldX, oldY, oldWidth, oldHeight;

  public void mousePressed(MouseEvent e) {
    start = e.getPoint();
    oldX = startX;
    oldY = startY;
    startX = e.getX();
    startY = e.getY();
    status.setText(String.format("Mouse start: " + start));
  }

  public void mouseDragged(MouseEvent e) {
    Graphics2D gc = (Graphics2D)canvas.getGraphics();
    gc.setColor(new Color(128, 218, 255));
    gc.drawOval(oldX, oldY, oldWidth, oldHeight);
    System.out.printf("oldWidth ist = %3d, oldHeight ist = %3d\n", oldWidth, oldHeight);
    oldWidth = e.getX();
    oldHeight = e.getY();
    gc.setColor(Color.BLACK);
    gc.drawOval(startX, startY, e.getX(), e.getY());
  }

  public void mouseReleased(MouseEvent e) {
    end = e.getPoint();
    status.setText(String.format("Mouse end: " + end));
  }
}


@Override
public void componentHidden(ComponentEvent e) {
    // TODO Auto-generated method stub

}
@Override
public void componentMoved(ComponentEvent e) {
    // TODO Auto-generated method stub

}
@Override
public void componentResized(ComponentEvent e) {
    // TODO Auto-generated method stub

}
@Override
public void componentShown(ComponentEvent e) {
    // TODO Auto-generated method stub

}
}

您可以将形状放置在某种容器中,如ArrayList。
paintComponent(Graphics g)内部,您应该从该列表中绘制每个形状,在actionPerformed(ActionEvent e)内部,您应该对绘制的对象使用repaint()方法。

您可以将形状放置在某种容器中,如ArrayList。 在paintComponent(Graphics g)内部,您应该从该列表中绘制每个形状,在actionPerformed(ActionEvent e)内部,您应该在绘制的对象上使用repaint()方法。

不要

Graphics2D gg = (Graphics2D) canvas.getGraphics();
这不是定制绘画的方式。Swing将询问您何时需要绘制某些内容,您需要重新绘制组件的当前状态

首先看一看和了解更多细节

基本上,您需要覆盖
JPanel
paintComponent
方法(确保首先调用
super.paintComponent
)并绘制组件的当前状态

您需要以对您最有用的任何形式存储状态(一个
列表
或自定义对象,甚至一个
图像

当您更改状态时,可以通过调用
repaint
请求API更新UI

不要执行

Graphics2D gg = (Graphics2D) canvas.getGraphics();
这不是定制绘画的方式。Swing将询问您何时需要绘制某些内容,您需要重新绘制组件的当前状态

首先看一看和了解更多细节

基本上,您需要覆盖
JPanel
paintComponent
方法(确保首先调用
super.paintComponent
)并绘制组件的当前状态

您需要以对您最有用的任何形式存储状态(一个
列表
或自定义对象,甚至一个
图像


更改状态后,可以通过调用
repaint
请求API更新UI

为什么此代码仍使用getGraphics()???另外一个问题明确告诉您不要使用getGraphics()!!!注意你的另一个问题。如果您希望以增量方式向绘制中添加椭圆,则需要创建一个
addOval(…)
type方法。在绘画方法中你不会这样做。您还收到了一些工作示例。从工作代码开始,修改工作代码。你是对的,对不起。不会再发生了。我将查看这些内容并再次尝试为什么此代码仍然使用getGraphics()???另外一个问题明确告诉您不要使用getGraphics()!!!注意你的另一个问题。如果您希望以增量方式向绘制中添加椭圆,则需要创建一个
addOval(…)
type方法。在绘画方法中你不会这样做。您还收到了一些工作示例。从工作代码开始,修改工作代码。你是对的,对不起。不会再发生了。我会检查这些东西,然后再试一次