java - 绘制树不可见;可能是布局问题

标签 java swing graphics jpanel draw

我想显示一棵树。 但树并没有出现。 有什么问题吗?

主要:

package scanner_parser;
public class Main {
    public static void main(String[] args) {
        Oberflaeche gui = new Oberflaeche();
        gui.setVisible(true);
    }
}

图形用户界面:

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

public class Oberflaeche extends JFrame implements ActionListener {

    private JPanel cp, top, bottom;
    private JTextField eingabefeld = new JTextField();
    private JButton button = new JButton("Darstellen");
    private JMenuBar menubar = new JMenuBar();
    private JMenu menu;
    private JMenuItem anleitung, beenden, bEins, bZwei, bDrei, bVier;
    private Baum baum = new Baum();

    public Oberflaeche() {
        this.setTitle("Funktionsparser");
        this.setSize(900, 700);
        this.setLocation(300, 100);
        this.setResizable(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        initMenu();

        cp = (JPanel) this.getContentPane();
        cp.setLayout(new BorderLayout(2, 1));
        top = new JPanel();
        top.setLayout(null);
        top.setBounds(0, 0, getWidth(), 50);
        top.setBackground(Color.white);

        bottom = new JPanel();
        bottom.setBounds(0, 50, getWidth(), getHeight() - 50);
        bottom.setBackground(Color.white);

        eingabefeld.setBounds(10, 10, getWidth() - 120, 30);
        button.setBounds(getWidth() - 110, 10, 100, 30);
        button.addActionListener(this);

        top.add(button);
        top.add(eingabefeld);
        cp.add(top);
        cp.add(bottom);
    }

    // Initialise Menu

    private void initMenu() {
        menu = new JMenu("Datei");
        anleitung = new JMenuItem("Anleitung");
        anleitung.addActionListener(this);

        menu.add(anleitung);
        beenden = new JMenuItem("Beenden");
        beenden.addActionListener(this);

        menu.add(beenden);
        menubar.add(menu);

        menu = new JMenu("Beispiele");

       // Load some example functions into the textfield

        bEins = new JMenuItem("<html>3 * x</html>");
        bEins.addActionListener(this);
        menu.add(bEins);

        bZwei = new JMenuItem("<html>3 * x<sup>2</sup></html>");
        bZwei.addActionListener(this);
        menu.add(bZwei);

        bDrei = new JMenuItem("<html>3 * ( x<sup>2</sup> + 1 )</html>");
        bDrei.addActionListener(this);
        menu.add(bDrei);

        bVier = new JMenuItem("<html>3 * ( x<sup>2</sup> + x<sup>4</sup> + 1 )</html>");
        bVier.addActionListener(this);
        menu.add(bVier);

        menubar.add(menu);

        this.setJMenuBar(menubar);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object s = e.getSource();

        if (s == anleitung) {

        }

       // This should add the tree (baum) but it does not appear.


        if (s == button) {
            FuncParser.theParser().parse(eingabefeld.getText());
            FuncParser.theParser().getWurzel().print();
            bottom.add(baum);
        }
        if (s == beenden) {
            System.exit(0);
        }
        if (s == bEins) {
            eingabefeld.setText("3*x");
        }
        if (s == bZwei) {
            eingabefeld.setText("3*x^2");
        }
        if (s == bDrei) {
            eingabefeld.setText("3*(x^2+1)");
        }
        if (s == bVier) {
            eingabefeld.setText("3*(x^2+x^4+1)");
        }
    }
}

树类:

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

public class Baum extends JPanel {

    private final int radius = 20;
    private final int paddingY = 75;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        System.out.println("test");
        displayBaum(g, FuncParser.theParser().getWurzel(), getWidth() / 2, 100, 20 + getWidth() / 4);
    }

    private void displayBaum(Graphics g, Knoten k, int x, int y, int paddingX) {
        g.drawOval(x - radius, y - radius, 2 * radius, 2 * radius);
        g.drawString(k.getDaten(), x - 4, y + 4);

        if (k.getLinks() != null) {
            displayKante(g, x - paddingX, y + paddingY, x, y);
            displayBaum(g, k.getLinks(), x - paddingX, y + paddingY, 10 + paddingX / 2);
            displayKante(g, x + paddingX, y + paddingY, x, y);
            displayBaum(g, k.getLinks(), x + paddingX, y + paddingY, 10 + paddingX / 2);
        }
    }

    private void displayKante(Graphics g, int x1, int y1, int x2, int y2) {
        double d = Math.sqrt(paddingY * paddingY + (x2 - x1) * (x2 - x1));
        int x11 = (int) (x1 - radius * (x1 - x2) / d);
        int y11 = (int) (y1 - radius * (y1 - y2) / d);
        int x21 = (int) (x2 + radius * (x1 - x2) / d);
        int y21 = (int) (y2 + radius * (y1 - y2) / d);
        g.drawLine(x11, y11, x21, y21);
    }
}

每次缩放窗口时,控制台中都会出现文本“test”。 这意味着该函数被调用,但树不会出现在内容 Pane 上。也许它下面有什么东西?我现在不明白为什么。如果您有想法,请帮忙。

最佳答案

将片段减少到可编译状态,我得到以下结果。特别是,

  • 不要使用null布局;该示例对 JFrame 使用默认的 BorderLayout,对 Panel 使用默认的 FlowLayout

  • 使用JTextField构造函数,可让您以列为单位指定字段的宽度。

  • 覆盖getPreferredSize()建立绘图区域的初始几何形状,并相对于其当前尺寸进行绘制。

  • event dispatch thread 上构造和操作 Swing GUI 对象.

  • ActionListener 中优先使用 equals() 而不是 ==

image

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
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;

/**
 * @See https://stackoverflow.com/a/38215252/230513
 */
public class Main {

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            Oberflaeche gui = new Oberflaeche();
            gui.setVisible(true);
        });
    }

    private static class Baum extends JPanel {

        private final int radius = 20;
        private final int paddingY = 75;

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawString("Hello", 16, 16);
            displayKante(g, 0, 0, getWidth(), getHeight());
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(329, 240);
        }

        private void displayKante(Graphics g, int x1, int y1, int x2, int y2) {
            double d = Math.sqrt(paddingY * paddingY + (x2 - x1) * (x2 - x1));
            int x11 = (int) (x1 - radius * (x1 - x2) / d);
            int y11 = (int) (y1 - radius * (y1 - y2) / d);
            int x21 = (int) (x2 + radius * (x1 - x2) / d);
            int y21 = (int) (y2 + radius * (y1 - y2) / d);
            g.drawLine(x11, y11, x21, y21);
        }
    }

    private static class Oberflaeche extends JFrame implements ActionListener {

        private JPanel top, bottom;
        private JTextField eingabefeld = new JTextField(20);
        private JButton button = new JButton("Darstellen");
        private JMenuBar menubar = new JMenuBar();
        private JMenu menu;
        private JMenuItem anleitung, beenden, bEins, bZwei, bDrei, bVier;
        private Baum baum = new Baum();

        public Oberflaeche() {
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            this.setTitle("Funktionsparser");
            initMenu();
            top = new JPanel();
            top.setBackground(Color.white);
            top.add(button);
            top.add(eingabefeld);
            button.addActionListener(this);
            bottom = new JPanel();
            bottom.setBackground(Color.white);
            bottom.add(new JLabel("Label text."));
            this.add(top, BorderLayout.NORTH);
            this.add(baum);
            this.add(bottom, BorderLayout.SOUTH);
            this.pack();
            this.setLocationRelativeTo(null);
        }

        // Initialise Menu
        private void initMenu() {
            menu = new JMenu("Datei");
            anleitung = new JMenuItem("Anleitung");
            anleitung.addActionListener(this);
            menu.add(anleitung);
            beenden = new JMenuItem("Beenden");
            beenden.addActionListener(this);
            menu.add(beenden);
            menubar.add(menu);
            menu = new JMenu("Beispiele");
            // Load some example functions into the textfield
            bEins = new JMenuItem("<html>3 * x</html>");
            bEins.addActionListener(this);
            menu.add(bEins);
            bZwei = new JMenuItem("<html>3 * x<sup>2</sup></html>");
            bZwei.addActionListener(this);
            menu.add(bZwei);
            bDrei = new JMenuItem("<html>3 * ( x<sup>2</sup> + 1 )</html>");
            bDrei.addActionListener(this);
            menu.add(bDrei);
            bVier = new JMenuItem("<html>3 * ( x<sup>2</sup> + x<sup>4</sup> + 1 )</html>");
            bVier.addActionListener(this);
            menu.add(bVier);
            menubar.add(menu);
            this.setJMenuBar(menubar);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            Object s = e.getSource();
            if (s == anleitung) {
                System.out.println(anleitung);
            }
            if (s == button) {
                System.out.println(button);
            }
            if (s == beenden) {
                System.exit(0);
            }
            if (s == bEins) {
                eingabefeld.setText("3*x");
            }
            if (s == bZwei) {
                eingabefeld.setText("3*x^2");
            }
            if (s == bDrei) {
                eingabefeld.setText("3*(x^2+1)");
            }
            if (s == bVier) {
                eingabefeld.setText("3*(x^2+x^4+1)");
            }
        }
    }
}

关于java - 绘制树不可见;可能是布局问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38209846/

相关文章:

java - 为什么eclipse不显示任何信息

java - 验证字符串没有非法字符

java - 计时器 - 如何使用 Joda Time 计算两个日期之间的差异?

java - 选项卡的组件未显示

java - GUI 组件 ActionListener 的最佳实践?

java - 未装饰按钮 : JButton or JLabel with MouseListener?

delphi - TWICImage : How to overlay transparent PNG on JPG?

c - 使用 MoveToEx 和 LineTo 为窗口制作边框

java - 如何在 Java 中为笑脸画嘴

java - Netty- 无法访问类 jdk.internal.misc.Unsafe