1

メニューベースのグラフを実装しようとしています-ここでは、頂点を円で表し、各円にはユーザーが提供するインデックスがあります。ユーザーは、[ファイル]メニューに移動し、[Addvertex]をクリックして、新しいノードを作成する必要があります。 index。しかし問題は-円が一度だけ描かれる-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

いくつかのポインタ:

  • Swingコンポーネントの作成と操作にはEDTを使用します。

  • JFrame不必要にクラスを拡張しないでください。

  • 可能な場合/許可されている場合は匿名 Listener使用する

  • 特にここを指しているインスタンスJFrame#setVisible(..)の最後の呼び出しであることを確認してください。JFrame

        this.setVisible(true);
        this.setSize(500, 500);
        this.setLocationRelativeTo(null);
        HelloHere(index.toString());
    
  • pack()ではJFrameなくインスタンスで呼び出すsetSize(..)

  • 複数を使用しないでください。複数のJFrameの使用:良い方法か悪い方法かを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();を呼び出すたびに新しいRandomインスタンスを開始するかのようpaintComponent()に、重要/ランダムではありません。

于 2012-11-12T16:17:56.030 に答える
2

ユーザーが新しいノードを作成するたびに、アプリケーションJPanelのに追加される新しいノードを作成しJFrameます。特定のレイアウトがない場合は、を使用しBorderLayoutます。BorderLayout各場所に複数のコンポーネントを追加することはできません。他のへの呼び出しaddはおそらく無視されます。

于 2012-11-12T15:54:45.750 に答える