1

我正在尝试实现一个基于菜单的图形 - 其中我将用一个圆圈表示一个顶点,每个圆圈将有一个用户提供的索引。用户必须转到文件菜单并单击 Addvertex 以创建一个新节点index.The 问题虽然是 - 圆圈只绘制一次 - 任何后续点击 addVertex 都不会导致绘制圆圈 - 不明白为什么......

这是我的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.*;

public class FileChoose extends JFrame {

    public FileChoose() {
        JMenuBar l=new JMenuBar();
        JMenu file=new JMenu("File");
        JMenuItem open=new JMenuItem("Addvertex");
        open.addActionListener(new Drawer());
        JMenuItem close=new JMenuItem("Exit");
        close.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        JMenu tools=new JMenu("Tools");
        file.add(open);
        file.add(close);

        this.setJMenuBar(l);
        l.add(tools);
        l.add(file);

        this.setSize(new Dimension(200, 200));
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
    }

    void HelloHere(String p) {
        Draw d = new Draw(p);
        this.add(d);
        setExtendedState(MAXIMIZED_BOTH);
    }

    class Drawer extends JFrame implements ActionListener {

        Integer index;

        public void actionPerformed(ActionEvent e) {
            JPanel pn = new JPanel();
            JTextField jt = new JTextField(5);
            JTextField jt1 = new JTextField(5);
            pn.add(jt);
            pn.add(jt1);
            int result=JOptionPane.showConfirmDialog(null, pn, "Enter the values", JOptionPane.OK_CANCEL_OPTION);
            if (result == JOptionPane.OK_OPTION) {
                index = Integer.parseInt(jt.getText());
                System.out.println(jt1.getText());
            }

            this.setVisible(true);
            this.setSize(500, 500);
            this.setLocationRelativeTo(null);

            HelloHere(index.toString());
        }
    }

    public static void main(String [] args) {
        FileChoose f = new FileChoose();
        f.setVisible(true);
    }
}

class Draw extends JPanel {

    String inp;

    public Draw(String gn) {
        inp = gn;
    }

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

        Graphics2D g2 = (Graphics2D) g;
        Random r = new Random();
        int x = r.nextInt(100);

        g2.drawOval(x, x * 2, 100, 100);
        g2.drawString(inp, x + (x / 2), x + (x / 2));
    }
}
4

2 回答 2

4

一些指示:

  • 使用EDT创建和操作 Swing 组件。

  • JFrame不要不必要地扩展课程。

  • 在可能/允许情况下使用匿名 Listener

  • 确保JFrame#setVisible(..)JFrame实例的最后一次调用专门指向此处:

        this.setVisible(true);
        this.setSize(500, 500);
        this.setLocationRelativeTo(null);
        HelloHere(index.toString());
    
  • 调用实例pack()JFrame不是setSize(..)

  • 不要使用多个JFrames 请参阅:多个 JFrame 的使用:好的还是坏的做法?

  • 您遇到的问题在这里:

    Draw d = new Draw(p);
    this.add(d);
    

    Draw JPanel您每次都创建一个新实例,然后用新实例覆盖最后JPanel添加的实例(这是 的默认行为BorderLayout)。要解决这个问题,请阅读以下 2 点:

  • 添加组件后调用revalidate()repaint()实例以显示新添加的组件。

  • 使用适当的LayoutManager

由于我不确定您的预期结果,我已经尽可能多地修复了代码,希望它有所帮助:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import javax.swing.*;

public class FileChoose {

    JFrame frame;

    public FileChoose() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JMenuBar l = new JMenuBar();
        JMenu file = new JMenu("File");
        JMenuItem open = new JMenuItem("Addvertex");

        open.addActionListener(new ActionListener() {
            Integer index;

            @Override
            public void actionPerformed(ActionEvent e) {
                JPanel pn = new JPanel();
                JTextField jt = new JTextField(5);
                JTextField jt1 = new JTextField(5);
                pn.add(jt);
                pn.add(jt1);
                int result = JOptionPane.showConfirmDialog(null, pn, "Enter the values", JOptionPane.OK_CANCEL_OPTION);
                if (result == JOptionPane.OK_OPTION) {
                    index = Integer.parseInt(jt.getText());
                    System.out.println(jt1.getText());
                }
                HelloHere(index.toString());
            }
        });

        JMenuItem close = new JMenuItem("Exit");
        close.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        JMenu tools = new JMenu("Tools");
        file.add(open);
        file.add(close);

        frame.setJMenuBar(l);
        l.add(tools);
        l.add(file);
        frame.pack();

        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    void HelloHere(String p) {
        Draw d = new Draw(p);
        frame.add(d);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.revalidate();
        frame.repaint();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                FileChoose f = new FileChoose();
            }
        });
    }
}

class Draw extends JPanel {

    String inp;

    public Draw(String gn) {
        inp = gn;
    }

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

        Graphics2D g2 = (Graphics2D) g;
        Random r = new Random();
        int x = r.nextInt(100);

        g2.drawOval(x, x * 2, 100, 100);
        g2.drawString(inp, x + (x / 2), x + (x / 2));
    }
}

更新

在您的 Draw 类中全局声明这一点:Random r=new Random();就好像您每次调用paintComponent()分布时都会启动一个新的 Random 实例,这将不够重要/随机

于 2012-11-12T16:17:56.030 回答
2

Every time the user creates a new node you create a new JPanel that is added to the JFrame of your application. In the absence of a specific layout it uses a BorderLayout. BorderLayout does not allow for more than one component to be added at each location. Your other calls to add are probably ignored.

于 2012-11-12T15:54:45.750 回答