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

时间:2014-05-26 00:49:05

标签: java swing localization jpanel jbutton

我似乎无法将按钮的自定义位置设置为 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 个答案:

答案 0 :(得分:2)

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

您的大型机布局是FlowLayout

  

mainframe.setLayout(new FlowLayout());

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

  

mainframe.add(MusicPanel,BorderLayout.SOUTH);

通过这样做,您无法真正预测GUI在编译时的外观。这可能是您问题的根源。

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


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

让我知道这是怎么回事!

答案 1 :(得分:2)

enter image description here

此MCVE使用标准JSE布局,插图和边框来创建上面显示的G​​UI。 GUI中空白区域的技巧在源代码中被注释为// 1,这可以用简单(但更长)的指令// Adjust numbers as required来解释。

将它拖得更宽更高,看看:

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

答案 2 :(得分:1)

我认为你应该对java中的布局做一些研究。 制作frame.setVisible(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);
        }
    }
}

这是操作效果。 enter image description here