【问题标题】:Why is my JPanel messing with other components on my JFrame?为什么我的 JPanel 会弄乱我的 JFrame 上的其他组件?
【发布时间】:2013-08-04 00:44:30
【问题描述】:

所以我有一个 JFrame,其中包含一个 JPanel,其中包含一个 JList 组件。

然后我有另一个 JPanel 用于我的 paintComponent(),它也返回一个维度。

但是当我设置维度的大小时,它会尝试重新定位我的另一个 JPanel。

这是我的paintComponent() 代码:

class drawOnPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.BLUE);
    }
    @Override
  public Dimension getPreferredSize(){
    return new Dimension(250, 250);
  }
}

然后我有调用 drawOnPanel 类的 JFrame:

public static void mainFrame() {
    JFrame f = new MTGSAMPServerReference();
    f.setTitle("MTG SAMP Server Reference Guide");
    f.pack();
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(new drawOnPanel());
    f.setSize(330, 300);
    f.setLocationRelativeTo(null);
}

然后我的 JPanel 上有我的 JList:

public void MainMenu() {
    JPanel controls = new JPanel(new BorderLayout(5,5));
    final CardLayout cl = new CardLayout();
    final JPanel panel = new JPanel(cl);
    controls.add(panel);
    this.getContentPane().setLayout(new FlowLayout(FlowLayout.LEADING));
        list = new JList<Object>(mainMenu);
        list.setVisibleRowCount(7);
        select = new JButton("Select");
        exit = new JButton("Exit");
        select.addActionListener(this);
        exit.addActionListener(this);
        controls.add(new JScrollPane(list));
        JPanel basePanel = new JPanel(new GridLayout(0, 1));
        basePanel.add(select);
        basePanel.add(exit);
        controls.add(basePanel, BorderLayout.PAGE_END);
        add(controls);
        refreshFrame();
}

当我尝试在paintComponent() JPanel 上绘图时,它会绘图,但我指示的坐标未正确绘制。

有人知道为什么会这样吗?

提前致谢!

编辑:这是我的程序的一些屏幕截图。

这是我的程序在我不包含drawOnPanel 时的样子:

当我包含drawOnPanel 时,这就是我的程序的样子:

我只希望它在 JList 的右侧绘制,而不移动 JList。如您所见,它调整了另一个 JPanel。

感谢您的任何帮助!

编辑:这是我的SSCCE

编辑:这是我的 SSCCE 代码:

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

public final class SSCCE1 extends JFrame implements ActionListener {
    private static final long serialVersionUID = 1L;
    JList list;
    JButton select;
    JButton exit;
    Object[]mainMenu = {"Value 1", "Value 2", "Value 3", "Value 4"};

    public SSCCE1() {
        MainMenu();
    }

    public void MainMenu() {
        JPanel controls = new JPanel(new BorderLayout(5,5));
        final CardLayout cl = new CardLayout();
        final JPanel panel = new JPanel(cl);
        controls.add(panel);
        this.getContentPane().setLayout(new FlowLayout(FlowLayout.LEADING));
            list = new JList<Object>(mainMenu);
            list.setVisibleRowCount(7);
            select = new JButton("Select");
            exit = new JButton("Exit");
            controls.add(new JScrollPane(list));
            JPanel basePanel = new JPanel(new GridLayout(0, 1));
            basePanel.add(select);
            basePanel.add(exit);
            controls.add(basePanel, BorderLayout.PAGE_END);
            add(controls);
            revalidate();
            repaint();
            SSCCE1.this.repaint();
    }

    public void createAndShowGUI() {
        mainFrame();
        SSCCE1.this.repaint();
    }

    public static void mainFrame() {
        JFrame f = new SSCCE1();
        f.setTitle("My SSCCE");
        f.pack();
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new drawOnPanel()); // When this is uncommented, it messes with the other JPanel, but when commented, it works fine, but does not allow drawing on the other JFrame.
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
        f.setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
            SSCCE1 gui = new SSCCE1();
            gui.createAndShowGUI();
            }
        });
    }
    @Override
    public void actionPerformed(ActionEvent ae) {
    }
}

class drawOnPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.BLUE);
    }
  @Override
  public Dimension getPreferredSize(){
    return new Dimension(250, 250);
  }
}

【问题讨论】:

  • 看起来是布局问题,但如果没有可运行的示例,将很难弄清楚原因
  • @MadProgrammer 最好的调试方法是什么?我一直在寻找一个交互式编译器,当您单击它时,它会向您显示每个组件是什么,但找不到...我确实得到了一个名为 PixelWindow 的程序来帮助我找出像素位置关闭的原因,但是问题在那部分不断变化。你会建议我做什么?
  • @MadProgrammer 你想让我粘贴我的代码吗?

标签: java swing jpanel paintcomponent dimension


【解决方案1】:

使setVisible()last,经过添加、打包和定位。完整示例见herehere

f.add(…);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);

附录:这是您的示例的一个变体,没有不可见的面板。如果没有令人信服的理由来扩展 JFrame,只需创建一个并添加您的组件。

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

/** @see https://stackoverflow.com/a/18038765/230513 */
public class SSCCE2 {

    private JList list;
    private JButton select;
    private JButton exit;
    private Object[] mainMenu = {"Value 1", "Value 2", "Value 3", "Value 4"};

    public JPanel mainMenu() {
        JPanel controls = new JPanel(new BorderLayout(5, 5));
        list = new JList(mainMenu);
        list.setVisibleRowCount(7);
        select = new JButton("Select");
        exit = new JButton("Exit");
        controls.add(new JScrollPane(list));
        JPanel basePanel = new JPanel(new GridLayout(0, 1));
        basePanel.add(select);
        basePanel.add(exit);
        controls.add(basePanel, BorderLayout.PAGE_END);
        return controls;
    }

    public void createAndShowGUI() {
        JFrame f = new JFrame("My SSCCE");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new DrawOnPanel());
        f.add(mainMenu(), BorderLayout.WEST);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                SSCCE2 gui = new SSCCE2();
                gui.createAndShowGUI();
            }
        });
    }

    private static class DrawOnPanel extends JPanel {

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLUE);
            g.fillRect(0, 0, getWidth(), getHeight());
        }

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

【讨论】:

  • 我只是按照你说的顺序重新排列它们。
  • @knorberg:那么如果它不起作用,那么您尚未向我们展示的代码中有问题。强烈考虑创建和发布sscce。虽然这需要相当多的努力来创造,但相信我,付出的努力是值得的。
  • @HovercraftFullOfEels 我现在发布了一个 SSCCE。
  • @knorberg:您需要在您的问题中发布您的 SSCCE,而不是作为链接。
  • @HovercraftFullOfEels 哦。对此感到抱歉。
猜你喜欢
  • 2015-12-13
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 2020-08-17
  • 2012-01-23
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
相关资源
最近更新 更多