当前位置: 首页 > 知识库问答 >
问题:

如何在JPanel中自定义位置放置JButton?

梁丘兴腾
2023-03-14

我似乎无法为JPanel设置按钮的自定义位置。它总是在左上角添加按钮,然后继续向右。我还有一个背景图像,这让事情变得更加困难。框架如下所示:imageshack.com/a/img838/3240/ez6l.png我的代码是:

private JFrame mainframe =  new JFrame();

public void main()
    {
    mainframe.setLocation(400, 150);
    mainframe.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    mainframe.setVisible(true);
    mainframe.setSize(800, 600);
    JPanel menupanel2 = new JPanel();
    JPanel MusicPanel = new JPanel();
    mainframe.setResizable(false);
    mainframe.setContentPane(new JLabel(new ImageIcon("src/res/LED0.png")));
    mainframe.setLayout(new FlowLayout());
    menupanel2.setBackground(Color.black);
    JButton PlayButton = new JButton("Play");
    PlayButton.setBackground(Color.green);
    JButton highscores = new JButton("Highscores");
    highscores.setBackground(Color.MAGENTA);
    JButton CustomButton = new JButton("Custom Shapes");
    CustomButton.setBackground(Color.orange);
    JButton HelpButton = new JButton("Help");
    HelpButton.setBackground(Color.red);
    JButton AboutButton = new JButton("About");
    AboutButton.setBackground(Color.yellow);
    final JButton MusicButton = new JButton("music");
    MusicButton.setPreferredSize(new Dimension(50, 50));
    CustomButton.setPreferredSize(new Dimension(140, 40));
    PlayButton.setPreferredSize(new Dimension(140, 40));
    HelpButton.setPreferredSize(new Dimension(140, 40));
    AboutButton.setPreferredSize(new Dimension(140, 40));
    highscores.setPreferredSize(new Dimension(140, 40));
    mainframe.add(menupanel2, BorderLayout.NORTH);
    mainframe.add(MusicPanel, BorderLayout.SOUTH);
    menupanel2.add(PlayButton, BorderLayout.NORTH);
    menupanel2.add(CustomButton, BorderLayout.NORTH);
    menupanel2.add(HelpButton, BorderLayout.NORTH);
    menupanel2.add(highscores, BorderLayout.NORTH);
    menupanel2.add(AboutButton, BorderLayout.NORTH);
    MusicPanel.add(MusicButton, BorderLayout.SOUTH);

我想将按钮“MusicButton”添加到右下角/中间/或左侧。如果您可以在JPanel中定制JButton,请分享。谢谢

共有3个答案

刘乐童
2023-03-14

我认为你应该研究一下java中的布局。让< code > frame . set可见(true)是个好习惯;在代码的最后。以下是我的解决方案,希望能帮到你。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;



public class LayoutDemo {
    public static void main(String[] args) {
        LayoutDemo gridLayoutDemo = new LayoutDemo();
        try {
            gridLayoutDemo.createUI();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.println("File read exception");
            e.printStackTrace();
        }
    }

    public void createUI() throws IOException{
        JFrame frame = new JFrame("Grid Layout");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        JPanel mainPanel = new MainPanel("background.png");

        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
        frame.add(mainPanel,BorderLayout.CENTER);
        JPanel topPanel = new JPanel();
        topPanel.setOpaque(false);
        mainPanel.add(topPanel);        
        mainPanel.add(Box.createVerticalStrut(500));        
        BottomPanel bottomPanel = new BottomPanel();
        mainPanel.add(bottomPanel); 

        frame.setSize(820, 620);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    @SuppressWarnings("serial")
    class MainPanel extends JPanel{
        private Image background;

        public MainPanel(String fileName) throws IOException{
            background = ImageIO.read(new File(fileName));
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(background, 0, 0, this);
        }
    }

    @SuppressWarnings("serial")
    class BottomPanel extends JPanel{
        public BottomPanel(){
            LeftPanel leftPanel = new LeftPanel();
            leftPanel.setOpaque(false);
            leftPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
            RightPanel rightPanel = new RightPanel();
            rightPanel.setBorder(new EmptyBorder(0, 0 , 0, 0));
            rightPanel.setOpaque(false);
            add(leftPanel,BorderLayout.WEST);
            add(rightPanel,BorderLayout.EAST);

            setOpaque(false);
        }
    }

    @SuppressWarnings("serial")
    class LeftPanel extends JPanel{
        public LeftPanel(){
            setLayout(new GridLayout(1,5,5,10));
            setBorder(new EmptyBorder(0, 5, 0, 55));
            setOpaque(false);
            JButton playButton = new JButton("Play");
            playButton.setBackground(Color.green);
            playButton.setPreferredSize(new Dimension(140, 40));
            add(playButton);

            JButton shapesButton = new JButton("Custom Shapes");
            shapesButton.setBackground(Color.orange);
            add(shapesButton);

            JButton helpButton = new JButton("Help");
            helpButton.setBackground(Color.red);
            add(helpButton);

            JButton scoresButton = new JButton("HighScores");
            scoresButton.setBackground(new Color(120,81,169));
            add(scoresButton);

            JButton aboutButton = new JButton("About");
            aboutButton.setBackground(Color.yellow);
            add(aboutButton);
        }

    }

    @SuppressWarnings("serial")
    class RightPanel extends JPanel{
        public RightPanel(){
            setBorder(new EmptyBorder(0, 0, 0, 0));
            JButton button = new JButton(new ImageIcon("buttonIcon.png"));
            button.setBorder(new EmptyBorder(0, 0, 0, 0));;
            add(button,BorderLayout.CENTER);
        }
    }
}
云季同
2023-03-14

该MCVE使用标准JSE布局、插图和边框来创建上述GUI。GUI中空白的技巧在源代码中被注释为<code>//1

把它拖得更宽更高,可以看到:

  • UI 的额外宽度在每个按钮之间大致相等地分配。“黑色”按钮粘附在 UI 的 RHS 上。
  • 额外高度显示在按钮的顶行和底部按钮之间。
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class ShapeShape {

    // the GUI as seen by the user (without frame)
    JPanel ui = new JPanel(new BorderLayout());

    public static final String[] ACTIONS = {
        "Play", "Custom Shapes", "Help", "High Scores", "About"
    };

    public static final Color[] COLORS = {
        Color.GREEN,Color.ORANGE,Color.RED,Color.MAGENTA,Color.YELLOW
    };

    ShapeShape() {
        initUI();
    }

    public void initUI() {
        ui.setBorder(new EmptyBorder(20, 30, 20, 30)); // 1

        JPanel menuPanel = new JPanel(new GridLayout(1, 0, 10, 10)); // 1
        ui.add(menuPanel, BorderLayout.PAGE_START); 
        Insets insets = new Insets(10, 20, 10, 20); // 1
        for (int ii=0; ii<ACTIONS.length; ii++) {
            JButton b = new JButton(ACTIONS[ii]);
            b.setMargin(insets);
            Font f = b.getFont();
            b.setFont(f.deriveFont(f.getSize()*1.4f)); // 1
            b.setBackground(COLORS[ii]);
            menuPanel.add(b);
        }

        Image img = new BufferedImage(60,60, BufferedImage.TYPE_INT_RGB);
        JPanel exitPanel = new JPanel(new FlowLayout(SwingConstants.RIGHT));
        exitPanel.setBorder(new EmptyBorder(15, 0, 0, 15)); // 1
        JButton b = new JButton(new ImageIcon(img));
        exitPanel.add(b);
        ui.add(exitPanel, BorderLayout.PAGE_END);
    }

    public final JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {

                ShapeShape o = new ShapeShape();

                JFrame f = new JFrame("Demo");
                f.add(o.getUI());
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}
全宪
2023-03-14

如果我错了,不要开始扔西红柿,但是......

您的大型机布局是 FlowLayout

mainframe.setLayout(new FlowLayout());

您正在指定将MusicPanel设置到为FlowLayout设置的JFrame上的BorderLayout位置。

mainframe.add(音乐面板,BorderLayout.SOUTH);

通过这样做,您无法真正预测您的GUI在compiles.This可能成为问题的根源时会是什么样子。

此外,另外,指南针参考不再是在 BorderLayout 中设置位置的首选方法。http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html

我会尝试将你的JFrame的布局设置为BorderLayout,将你的MusicPanel设置为JFrame的PAGE_END (SOUTH)位置。然后,使用MusicPanel上的GridBag布局,将JButton定位到LAST_LINE_END位置。

让我知道那是如何工作的!

 类似资料:
  • 但是,我的程序稍后尝试将一个新的JPanel添加到类的扩展JPanel中,方法是: 这个新的JPanel以正确的BorderLayout格式显示内容,但是JPanel本身将保持在扩展JPanel的顶部中心,我知道这是因为默认布局设置为FlowLayout,但是将其设置为BorderLayout只会导致面板占用整个屏幕。将布局设置为null将完全破坏框架,除了框架的最小化和关闭按钮之外,什么也没有出

  • 我正在使用Hibernate、JPA和Spring Boot。 我想持久化一个类型为“version”的自定义对象。“version”是一个处理复杂的对象,但它在表中对应于一个简单的VARCHAR字段。我能够从字符串构造版本和从版本对象构造字符串。 null 谢谢!!

  • 问题内容: 我将JPanel包裹在JScrollPane中,我希望始终将矩形绘制在同一位置上=使用滚动条移动不会影响矩形的可见性。 我尝试了以下代码: 但是仅当更改整个JPanel的大小时才重新绘制矩形。 问题答案: IIRC 将尝试最大程度地减少滚动完成时的重绘次数,因此它不会总是导致组件被更新。 标准技术是使用。将您添加到下层,并在其上面添加不透明的玻璃面板组件。请参阅Swing教程中的如何使

  • 问题内容: 我已经制作了一个自定义的nbconvert模板,并希望可以从启动实用程序的任何文件夹中对其进行访问。我应该在哪里放置模板? 我在官方文档中找不到任何内容。我已经尝试过平常的地方jupyter CONFIGS一样,,,无济于事。 到目前为止,我唯一找到的地方是python包所在的文件夹: 如果我在此处创建目录并将模板放在其中,则效果很好。但这是一个丑陋的hack,每次我更新nbconve

  • 我需要一个帮助来定位一个JPanel在一个特定的位置到一个Jframe。 我在一个扩展JFrame的类中有一个JPanel,我需要将这个JPanel放在一个特定的x,y位置。 是这样的: 我不需要一个LayoutManager的位置的JPanel,因为我需要把JPanel在一个特定的位置(像150,150的例子)。但是如果我panel.set位置(150,150),就像上面的代码一样,什么都不会发