簡體   English   中英

無法將JComponent添加到JPanel

[英]Can not add JComponent to JPanel

在添加從JComponent擴展到MyPanel類的類時遇到問題。 從JComboBox列表中選擇並按Start / Restart后,右側面板不會更新。 將所有繪圖內容添加到Panel MyComponent類后,即為平均值。 如果有人可以看一下並告訴我什么時候我在犯錯誤,或者是用其他不同的方式來做到這一點,請幫助我:)!

運行應用程序類:

import javax.swing.JFrame;

public class RunApp {

    public static void main(String[] args) {

        JFrame mainFrame = new MyPanel();
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        mainFrame.setVisible(true);


    }

}

MyPanel類別:

    import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;



public class MyPanel extends JFrame {

    private JPanel leftPanel = null;
    private JPanel rightPanel = null;
    private JPanel mainPanel = null;
    private JButton start = null;
    private JButton restart = null;
    private JComboBox<String> menuBox = new JComboBox<>();
    private Toolkit kit = Toolkit.getDefaultToolkit();
    private Dimension screenSize = kit.getScreenSize();
    private int screenHeight = screenSize.height;
    private int screenWidth = screenSize.width;

    public MyPanel() {

        mainPanel = new JPanel();

        mainPanel.setBackground(Color.orange);
        mainPanel.setPreferredSize(getPreferredSize());

        leftPanel = new JPanel();
        leftPanel.setBackground(Color.blue);
        leftPanel.setPreferredSize(new Dimension(screenWidth/6, screenHeight));

        menuBox.addItem("Gaussian Wave - non Dispersive");
        menuBox.addItem("Gaussian Wave - Dispersive");

        start = new JButton("Start");
        restart = new JButton("Restart");

        leftPanel.add(menuBox);
        leftPanel.add(start);
        leftPanel.add(restart);


        rightPanel = new JPanel();
        rightPanel.setBackground(Color.red);
        rightPanel.setPreferredSize(new Dimension(screenWidth -( screenWidth/5 ), screenHeight));

        start.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                if(menuBox.getItemAt(menuBox.getSelectedIndex()).equals("Gaussian Wave - non Dispersive")) {

                    rightPanel.add(new MyComponent());
                    rightPanel.revalidate();
                    rightPanel.repaint();


                } else if(menuBox.getItemAt(menuBox.getSelectedIndex()).equals("Gaussian Wave - Dispersive")) {

                    rightPanel.add(new MyComponent());
                    rightPanel.revalidate();

                    rightPanel.repaint();
                }
            }
        });


        restart.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                rightPanel.removeAll();
                rightPanel.revalidate();
                rightPanel.repaint();
                rightPanel.setBackground(Color.RED);
            }
        });

        mainPanel.add(leftPanel);
        mainPanel.add(rightPanel);
        add(mainPanel);



    }

    @Override
    public Dimension getPreferredSize() {

        return new Dimension(screenWidth, screenHeight);
    }

}

就像我說的那樣,以這種方式添加MyComponent類時無法正常工作。 通常,當我直接添加此類時,例如:

public MyPanel() {

    add(new MyComponent);

}

工作完美,但我想將其從列表中選擇后添加到划分的屏幕。 謝謝 !

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;
import java.util.function.Function;

import javax.swing.JComponent;

public class MyComponent extends JComponent {

private int wx, wy;

    private double xMin, xMax, yMin, yMax, xInc, time;



    private Function<Double, Double>gaussFunction;
    private Function<Double, Double>dispersiveGaussFunction;

    public MyComponent() {
        init();
    }


    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        makeGraphics(g2);

    }

    private void makeGraphics(Graphics2D g2) {

        GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
        if(time < 5) {
            countGaussianWave(this.time);

            double x = xMin;
            double y = gaussFunction.apply(x);


                path.moveTo(
                        mapX(x), mapY(y)
                        );
                x+=xInc;

                while(x < xMax) {
                    y = gaussFunction.apply(x);
                    path.lineTo(
                            mapX(x), mapY(y)
                            );
                        x+=xInc;
                }
                g2.draw(path);
                repaint();
                this.time+=0.001;

                if(this.time > 3.5) {
                    this.time = -3.5;

                    System.out.println(time);
                }
            }


    }


    private void init() {
        wx = 700;
        wy = 700;
        xMin = -1;
        xMax = 1;
        yMin = -1;
        yMax = 1;
        xInc = 0.01;
        setTime(time);
    }

    private double mapX(double x) {
        double fx = wx / 2;
        double sx = wx / (xMax - xMin);

        return x * fx + sx;
    }

    private double mapY(double y) {
        double fy = wy / 2;
        double sy = wy / (yMax - yMin); 

        return -y * sy + fy;
    }

    public void countGaussianWave(double time) {

        double lambda = 1;

        this.gaussFunction = x -> {
                return x = Math.exp(-(Math.pow((x-time ), 2)))
                        * (Math.cos((2*Math.PI*(x-time))/lambda)
                                + Math.sin((2*Math.PI*(x-time))/lambda)); // need complex
        };
    }

//  public void countDispersiveGaussianWave(double time) {
//      
//      double lambda = 1;
//      double k = (2 * Math.PI) / lambda;
//      
//      this.dispersiveGaussFunction = x -> {
//          return x = (1/(Math.sqrt(1 + 2 * time)) * 
//                  Math.exp(-(Math.pow((1 / Math.pow(1 + 4 * time, 2)) * (x - k * time), 2)))
//                  * Math.exp(Math.pow(, b));
//                  );
//      };
//  }

    public double getTime() {
        return time;
    }

    public void setTime(double time) {
        this.time = time;
    }


}

應用程序

比較對象時不要使用“ ==”。

相反,您應該使用equals(...)方法。

將組件添加(或刪除)到可見的GUI時,基本代碼為:

panel.add(...);
panel.revalidate();
panel.repaint();

基本上,您需要確保調用了布局管理器,否則組件的大小為(0,0),因此無需繪制任何內容。

另外,您需要重寫getPreferredSize()方法以返回組件的大小。 否則,大小為(0,0),因此沒有要繪畫的內容。

編輯

我猜您的組件未顯示是因為您的GUI設計不佳和值的硬編碼。 FlowLayout是一種可怕的布局,用於添加到框架的所有組件。 您需要努力使用適當的布局管理器在邏輯上組織面板上的組件。 添加大量組件后,這些組件將換行到第二行。 但是,首選大小不會自動更改,因此您可能看不到所有組件。 所以

rightPanel.setPreferredSize(new Dimension(...) );

不要硬編碼首選大小。 每個組件負責確定自己的大小,這就是為什么您override getPreferredSize()方法的原因。 這樣,布局管理者就可以正確地完成工作。 因此,擺脫所有setPreferrededSize()語句。

Jframe的默認布局是BorderLayout。 我會堅持那種布局。 不需要mainPanel,因為框架的內容窗格已經是JPanel。

因此,我將重命名您的“ leftPanel”,也許將其命名為“ topPanel”。 然后,您可以將固定組件添加到該面板並將該面板添加到框架:

JPanel topPanel = new JPanel();
topPanel.add( comboBox );
topPanel.add( startButton );
topPanel.add( restartButton );
frame.add(topPanel, BorderLayout.PAGE_START);

因此,這些組件將出現在框架的頂部。

現在也不需要“ rightPanel”。 相反,您可以直接將組件直接添加到框架中。

frame.add( new MyComponent(), BorderLayout.CENTER);
frame.revalidate();
frame.repaint();

現在,該組件將出現在框架的中央,並占用框架中所有可用的額外空間。

首先,您可以像這樣簡化“開始”按鈕的ActionListener邏輯

if(combobox.getSelectedItem().equals("Text")
{
    doSomething();
}

另外,添加或刪除新組件后,您需要調用“ 重新驗證並重新繪制”

如果你想在組件的一個油漆,確保@Override它並調用它的超方法super.paintComponent(g);

您還將2個動作偵聽器分配給同一按鈕。 我建議刪除其中之一

連同@Camickr的重寫getPreferredSize()方法的答案一樣,您應該將重新啟動按鈕的ActionListener更改為此

rightPanel.removeAll();
rightPanel.revalidate();
rightPanel.repaint();
rightPanel.setBackground(Color.RED);

您可以重寫getPreferredSize(); 像這樣的方法:

@Override
public Dimension getPreferredSize()
{
    int width = Toolkit.getDefaultToolkit().getScreenSize().width / 2;
    int height = Toolkit.getDefaultToolkit().getScreenSize().height;
    return new Dimension(width, height);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM