如何将按钮移动到确切位置?
How to move button to exact location?
我希望按钮和文本字段以与它们所在的布局相同的方式进入标记为红色的空间。查看图片以了解我的意思。
更新:按钮现在就位,但图像不会出现在第二个面板上
如何将它们移动到那里?到目前为止,这是我的代码
package gasindicator;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;
import java.io.*;
import javax.imageio.*;
import java.net.*;
public class GasIndicator extends JPanel
{
private Image image;
GasIndicator()
{
try
{
image = ImageIO.read(new URL("http://i68.tinypic.com/2ceja8i.png"));
}
catch (IOException ioe)
{
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
setLayout( new BorderLayout() );
JLabel background = new JLabel( new ImageIcon(image) );
background.setLayout( new FlowLayout(FlowLayout.LEFT) );
add( background );
JPanel buttonPanel = new JPanel( new GridLayout(0, 3, 6, 5) );
buttonPanel.setBorder( new EmptyBorder(338, 233, 0, 0) );
buttonPanel.setOpaque( false );
//for (int i = 0; i < 7; i++)
{
JButton button = new JButton("Button");
JButton button1 = new JButton("Button");
JButton button2 = new JButton("Button");
JButton button3 = new JButton("Button");
JButton button4 = new JButton("Button");
JButton button5 = new JButton("Button");
button.setPreferredSize( new Dimension(160, 45) );
buttonPanel.add(button);
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
buttonPanel.add(button4);
buttonPanel.add(button5);
button.addActionListener(new Action());
}
background.add( buttonPanel );
}
static class Action implements ActionListener {
public void actionPerformed(ActionEvent e) {
JFrame frame2 = new JFrame("Museums in London");
frame2.setVisible(true);
frame2.setSize(550, 650);
JPanel panel = new JPanel();
frame2.add(panel);
Custom contentPane;
// JFrame frame = new JFrame("JTextField");
contentPane = new Custom();
frame2.setContentPane(contentPane);
}
}
private static void ShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GasIndicator());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> ShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
class Custom extends JPanel {
public BufferedImage image;
public Custom() {
try {
image = ImageIO.read(new URL
("http://www.destination360.com/europe/uk/images/s/museums.jpg"));
} catch (IOException ioe) {
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
}
public Dimension getPreferredSize() {
return (new Dimension(image.getWidth(), image.getHeight()));
}
public void paintComponent(Graphics x) {
super.paintComponent(x);
x.drawImage(image, 10, 10, this);
}
}
}
这里的问题是您的面板上设置了标准布局管理器。
尝试用
禁用它
contentPane.setLayout(null);
然后您可以使用 button.setBountds(x,y,w,h);
随意移动按钮
我总是直接在框架上绘制,而不是像您那样使用自定义面板,但我看到在某些用例中这会是更好的方法。
如果你写
new JFrame.getContentPane().setLayout(null);
您的框架获得默认窗格,但其布局仍设置为空。
不同之处在于您可以直接添加到框架,而不是使用您放置东西的面板。
frame.add(new Button().setBounds(x,y,w,h));
试用我尝试调试的这个版本的代码:
Custom1 contentPane;
//at first create and set the frame
JFrame frame = new JFrame("Windowname goes here");
frame.setSize(1160, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
//next add your custom panel
contentPane = new Custom1();
frame.setContentPane(contentPane);
//better add this to the panel instead of the frame
JTextField textfield = new JTextField(20);
frame.add(textfield);
textfield.setBackground(Color.black);
textfield.setForeground(Color.white);
//you are using 2 panels with null layout here
JPanel panel = new JPanel();
panel.setSize(frame.getHeight(),frame.getWidth()); //give the panel some bounds!
panel.setOpaque(false); //unnecesary
panel.setLayout(null);
panel.setBackground(Color.BLACK);
frame.add(panel);
JButton button = new JButton("London");
JButton button1 = new JButton("Oxford");
JButton button2 = new JButton("Cambridge");
//you seemed to not have added these before
JButton button4 = new JButton("Click");
JButton button5 = new JButton("Click");
JButton button6 = new JButton("Click");
button.setBounds(60, 400, 220, 30);
button.setBackground(Color.black);
button.setForeground(Color.WHITE);
button1.setBounds(x,y,w,h); // !!!! <------
button1.setBackground(Color.black);
button1.setForeground(Color.WHITE);
button2.setBounds(x,y,w,h); // !!!! <------
button2.setBackground(Color.black);
button2.setForeground(Color.WHITE);
button4.setBounds(80, 50, 100, 30);
button5.setBounds(x,y,w,h); // !!!! <------
button6.setBounds(x,y,w,h); // !!!! <------
panel.add(button);
panel.add(button1);
panel.add(button2);
panel.add(button3);
panel.add(button4);
panel.add(button5);
panel.add(button6);
//SETVISIBLE ALWAYS GOES LAST
frame.setVisible(true);
我修补了您的代码并在其中写了一些注释。
我用 !!!!<---- 标记了您需要为按钮设置边界的位置,
您似乎为 button4 做了这个,但没有为其他按钮做这个。此外,您应该在代码中获得更好的结构,我不想侮辱您,但我会称之为 "spaghetti code"。
还有一些问题,例如您似乎根本没有添加按钮,但它们出现在您的图片中...
让我知道在试玩边界值并调查代码中的最终错误后它是否有效。
另外,如果你把整个项目发给我,我可以监督它,但最好自己尝试一下,如果别人做了你的工作,它不会给你任何东西。
祝你好运,编码愉快( ͡° ͜ʖ ͡°)
演示使用带边框的布局管理器概念的简单示例。按钮的大小也已调整为图像中按钮的大小:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;
import java.io.*;
import javax.imageio.*;
import java.net.*;
public class SSCCE extends JPanel
{
private Image image;
SSCCE()
{
try
{
image = ImageIO.read(new URL("http://i68.tinypic.com/2ceja8i.png"));
}
catch (IOException ioe)
{
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
setLayout( new BorderLayout() );
JLabel background = new JLabel( new ImageIcon(image) );
background.setLayout( new FlowLayout(FlowLayout.LEFT) );
add( background );
JPanel buttonPanel = new JPanel( new GridLayout(0, 3, 6, 5) );
buttonPanel.setBorder( new EmptyBorder(338, 233, 0, 0) );
buttonPanel.setOpaque( false );
for (int i = 0; i < 6; i++)
{
JButton button = new JButton("Button " + i);
button.setPreferredSize( new Dimension(160, 45) );
buttonPanel.add(button);
}
background.add( buttonPanel );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
是的,这些值仍有一些调整。但是用一个EmptyBorder调整整个面板的位置,所有按钮同时移动,比单独调整每个按钮的位置更容易。
注意:不要使用 JLabel 来显示图像,因为如果调整框架的大小,组件将会移动。而是使用您的自定义面板来绘制图像。
我希望按钮和文本字段以与它们所在的布局相同的方式进入标记为红色的空间。查看图片以了解我的意思。
更新:按钮现在就位,但图像不会出现在第二个面板上
如何将它们移动到那里?到目前为止,这是我的代码
package gasindicator;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;
import java.io.*;
import javax.imageio.*;
import java.net.*;
public class GasIndicator extends JPanel
{
private Image image;
GasIndicator()
{
try
{
image = ImageIO.read(new URL("http://i68.tinypic.com/2ceja8i.png"));
}
catch (IOException ioe)
{
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
setLayout( new BorderLayout() );
JLabel background = new JLabel( new ImageIcon(image) );
background.setLayout( new FlowLayout(FlowLayout.LEFT) );
add( background );
JPanel buttonPanel = new JPanel( new GridLayout(0, 3, 6, 5) );
buttonPanel.setBorder( new EmptyBorder(338, 233, 0, 0) );
buttonPanel.setOpaque( false );
//for (int i = 0; i < 7; i++)
{
JButton button = new JButton("Button");
JButton button1 = new JButton("Button");
JButton button2 = new JButton("Button");
JButton button3 = new JButton("Button");
JButton button4 = new JButton("Button");
JButton button5 = new JButton("Button");
button.setPreferredSize( new Dimension(160, 45) );
buttonPanel.add(button);
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
buttonPanel.add(button4);
buttonPanel.add(button5);
button.addActionListener(new Action());
}
background.add( buttonPanel );
}
static class Action implements ActionListener {
public void actionPerformed(ActionEvent e) {
JFrame frame2 = new JFrame("Museums in London");
frame2.setVisible(true);
frame2.setSize(550, 650);
JPanel panel = new JPanel();
frame2.add(panel);
Custom contentPane;
// JFrame frame = new JFrame("JTextField");
contentPane = new Custom();
frame2.setContentPane(contentPane);
}
}
private static void ShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GasIndicator());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> ShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
class Custom extends JPanel {
public BufferedImage image;
public Custom() {
try {
image = ImageIO.read(new URL
("http://www.destination360.com/europe/uk/images/s/museums.jpg"));
} catch (IOException ioe) {
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
}
public Dimension getPreferredSize() {
return (new Dimension(image.getWidth(), image.getHeight()));
}
public void paintComponent(Graphics x) {
super.paintComponent(x);
x.drawImage(image, 10, 10, this);
}
}
}
这里的问题是您的面板上设置了标准布局管理器。 尝试用
禁用它contentPane.setLayout(null);
然后您可以使用 button.setBountds(x,y,w,h);
我总是直接在框架上绘制,而不是像您那样使用自定义面板,但我看到在某些用例中这会是更好的方法。
如果你写
new JFrame.getContentPane().setLayout(null);
您的框架获得默认窗格,但其布局仍设置为空。
不同之处在于您可以直接添加到框架,而不是使用您放置东西的面板。
frame.add(new Button().setBounds(x,y,w,h));
试用我尝试调试的这个版本的代码:
Custom1 contentPane;
//at first create and set the frame
JFrame frame = new JFrame("Windowname goes here");
frame.setSize(1160, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
//next add your custom panel
contentPane = new Custom1();
frame.setContentPane(contentPane);
//better add this to the panel instead of the frame
JTextField textfield = new JTextField(20);
frame.add(textfield);
textfield.setBackground(Color.black);
textfield.setForeground(Color.white);
//you are using 2 panels with null layout here
JPanel panel = new JPanel();
panel.setSize(frame.getHeight(),frame.getWidth()); //give the panel some bounds!
panel.setOpaque(false); //unnecesary
panel.setLayout(null);
panel.setBackground(Color.BLACK);
frame.add(panel);
JButton button = new JButton("London");
JButton button1 = new JButton("Oxford");
JButton button2 = new JButton("Cambridge");
//you seemed to not have added these before
JButton button4 = new JButton("Click");
JButton button5 = new JButton("Click");
JButton button6 = new JButton("Click");
button.setBounds(60, 400, 220, 30);
button.setBackground(Color.black);
button.setForeground(Color.WHITE);
button1.setBounds(x,y,w,h); // !!!! <------
button1.setBackground(Color.black);
button1.setForeground(Color.WHITE);
button2.setBounds(x,y,w,h); // !!!! <------
button2.setBackground(Color.black);
button2.setForeground(Color.WHITE);
button4.setBounds(80, 50, 100, 30);
button5.setBounds(x,y,w,h); // !!!! <------
button6.setBounds(x,y,w,h); // !!!! <------
panel.add(button);
panel.add(button1);
panel.add(button2);
panel.add(button3);
panel.add(button4);
panel.add(button5);
panel.add(button6);
//SETVISIBLE ALWAYS GOES LAST
frame.setVisible(true);
我修补了您的代码并在其中写了一些注释。
我用 !!!!<---- 标记了您需要为按钮设置边界的位置,
您似乎为 button4 做了这个,但没有为其他按钮做这个。此外,您应该在代码中获得更好的结构,我不想侮辱您,但我会称之为 "spaghetti code"。
还有一些问题,例如您似乎根本没有添加按钮,但它们出现在您的图片中...
让我知道在试玩边界值并调查代码中的最终错误后它是否有效。 另外,如果你把整个项目发给我,我可以监督它,但最好自己尝试一下,如果别人做了你的工作,它不会给你任何东西。
祝你好运,编码愉快( ͡° ͜ʖ ͡°)
演示使用带边框的布局管理器概念的简单示例。按钮的大小也已调整为图像中按钮的大小:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;
import java.io.*;
import javax.imageio.*;
import java.net.*;
public class SSCCE extends JPanel
{
private Image image;
SSCCE()
{
try
{
image = ImageIO.read(new URL("http://i68.tinypic.com/2ceja8i.png"));
}
catch (IOException ioe)
{
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
setLayout( new BorderLayout() );
JLabel background = new JLabel( new ImageIcon(image) );
background.setLayout( new FlowLayout(FlowLayout.LEFT) );
add( background );
JPanel buttonPanel = new JPanel( new GridLayout(0, 3, 6, 5) );
buttonPanel.setBorder( new EmptyBorder(338, 233, 0, 0) );
buttonPanel.setOpaque( false );
for (int i = 0; i < 6; i++)
{
JButton button = new JButton("Button " + i);
button.setPreferredSize( new Dimension(160, 45) );
buttonPanel.add(button);
}
background.add( buttonPanel );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
是的,这些值仍有一些调整。但是用一个EmptyBorder调整整个面板的位置,所有按钮同时移动,比单独调整每个按钮的位置更容易。
注意:不要使用 JLabel 来显示图像,因为如果调整框架的大小,组件将会移动。而是使用您的自定义面板来绘制图像。