我似乎无法将按钮的自定义位置设置为 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,请分享。感谢
答案 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)
此MCVE使用标准JSE布局,插图和边框来创建上面显示的GUI。 GUI中空白区域的技巧在源代码中被注释为// 1
,这可以用简单(但更长)的指令// Adjust numbers as required
来解释。
将它拖得更宽更高,看看:
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);
}
}
}
这是操作效果。