绘图树不可见;也许布局问题

时间:2016-07-05 18:04:17

标签: java swing graphics jpanel draw

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

主:

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

GUI:

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);
    }
}

文字&#34;测试&#34;每次缩放窗口时都会出现在控制台中。 这意味着将调用该函数,但树不会出现在内容窗格中。也许它在底下?我现在不知道为什么。如果您有任何想法,请提供帮助。

2 个答案:

答案 0 :(得分:2)

将碎片缩减为可编辑状态,我得到以下结果。特别是,

  • 不要使用null布局;该示例使用BorderLayout的默认JFrameFlowLayout的{​​{1}}。

  • 使用JTextField构造函数,您可以在列中指定字段的宽度。

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

  • event dispatch thread上构建和操作仅的Swing GUI对象。

  • Panel equals()中使用==优先于ActionListener

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)");
            }
        }
    }
}

答案 1 :(得分:1)

您要将两个面板添加到内容窗格的中心cp,并且永远不会添加baum。在面板上使用约束如下:

cp.add(top, BorderLayout.NORTH);
cp.add(baum, BorderLayout.CENTER);
cp.add(bottom, BorderLayout.SOUTH);