我是JFrame的新手,我在NetBean中遇到布局问题,如何解决这个布局问题?我试图调整大小,但元素的位置会变得混乱。我试图将每个细节显示到指定的文本区域。 我使用错误的布局还是我的编码有问题?帮助...><
这些是我的编码:
public class PokemonJournal extends JFrame
implements ActionListener {
JTextArea FirstName = new JTextArea(1, 10);
JTextArea LastName = new JTextArea(1, 10);
JTextArea Level = new JTextArea(1, 10);
JTextArea Gender = new JTextArea(1, 10);
JButton showPokemon = new JButton("Show");
JButton showRaid = new JButton("Show");
JButton showPokestop = new JButton("Show");
DBHandler db = new DBHandler();
ImageIcon image = new ImageIcon("p1.jpg");
JLabel imageLabel = new JLabel(image);
public static void main(String[] args) {
PokemonJournal jf = new PokemonJournal();
}
public PokemonJournal() {
setLayout(new FlowLayout());
setSize(300, 600);
setTitle(" Pokemon Journal ");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLocationRelativeTo(null);
setResizable(false);
JPanel top = new JPanel();
add("north", top);
top.add(new Label("Pokemon Journal"));
JPanel side = new JPanel();
add("West", side);
side.setLayout(new GridLayout());
side.add(imageLabel);
JPanel line1 = new JPanel();
add("center", line1);
line1.setLayout(new GridLayout());
line1.add(new Label("First Name :"));
line1.add(FirstName);
JPanel line2 = new JPanel();
add("Center", line2);
FirstName.setEditable(false);
line2.setLayout(new GridLayout());
line2.add(new Label("Last Name :"));
line2.add(LastName);
LastName.setEditable(false);
JPanel line3 = new JPanel();
add("Center", line3);
line3.setLayout(new GridLayout());
line3.add(new Label("Level :"));
line3.add(Level);
Level.setEditable(false);
JPanel line4 = new JPanel();
add("Center", line4);
line4.setLayout(new GridLayout());
line4.add(new Label("Gender : "));
line4.add(Gender);
Gender.setEditable(false);
JPanel line5 = new JPanel();
add("Center", line5);
line5.setLayout(new GridLayout());
line5.add(new Label("Pokemon Caught:"));
line5.add(showPokemon);
JPanel line6 = new JPanel();
add("Center", line6);
line6.setLayout(new GridLayout());
line6.add(new Label("Raid Won:"));
line6.add(showRaid);
JPanel line7 = new JPanel();
add("Center", line7);
line7.setLayout(new GridLayout());
line7.add(new Label("Pokestop visited:"));
line7.add(showPokestop);
}
答案 0 :(得分:2)
我使用错误的布局还是我的编码有问题?
嗯,是的,有点,但它更多地与您的JFrame
的大小有关,从不在它们上面调用setSize()
,而是调用pack()
。但是,如果您将其更改为pack()
,则FlowLayout
的默认方向为FlowLayout.HORIZONTAL
,因此您的所有组件都将相互靠右。
然后,您有两个选择:
将JFrame
的布局保持为FlowLayout
,但制作两个JPanel
,一个用于图像,一个用于数据,图像可能包含默认FlowLayout
,但另一个可能有GridLayout
。
对所有组件使用GridBagLayout
,让图片JLabel
的高度为7个单元格,其他所有组件的高度为1。
对于以下示例,我将使用GridBagLayout
选项,我建议您尝试制作多面板选项(选项1)。
但是,在开始之前,我必须在您的代码中提及您的其他问题:
您未关注Java naming conventions:firstWordLowerCaseVariable
,firstWordLowerCaseMethods()
,FirstWordUpperCaseClasses
,ALL_WORDS_UPPER_CASE_CONSTANTS
,这将使您的代码更轻松为您和我们阅读和理解。
您并未改变JFrame
的行为,因此无需继承该行为:有关详细信息,请参阅Extends JFrame vs. creating it inside the program。
与上述相关,明智的做法是建立JPanel
而不是JFrame
s的GUI,请参阅:The Use of Multiple JFrames: Good or Bad Practice?,因为我认为你将来可能会遇到类似的问题。
您未将您的计划放在Event Dispatch Thread (EDT)上,请参阅此related answer以了解如何解决此问题。
您正在调用setSize(...)
方法,正如我之前所说,最好再调用pack()
方法,将GUI大小的计算留给布局管理员。
在将所有组件添加到GUI之前,您正在调用setVisible
,这可能会导致您出现空白或黑屏,它应该是您程序中的最后一行。
与上述内容相关,我总是喜欢从内到外开始使用GUI,并且不是在外面添加项目。
为什么您使用JTextArea
而不是JTextField
来获取用户信息?
现在,使用我给你的第二个选项遵循上述建议的代码是:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class PokemonJournal {
private JFrame frame;
private JPanel pane;
private GridBagConstraints gbc;
private JLabel imageLabel;
private JLabel firstName;
private JLabel lastName;
private JLabel level;
private JLabel gender;
private JLabel pokemonCaught;
private JLabel raidWon;
private JLabel pokestopVisited;
private JTextField nameField;
private JTextField lastNameField;
private JTextField levelField;
private JTextField genderField;
private JButton pokemonCaughtButton;
private JButton raidWonButton;
private JButton pokestopVisitedButton;
public static void main(String[] args) {
SwingUtilities.invokeLater(new PokemonJournal()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
pane = new JPanel();
pane.setLayout(new GridBagLayout());
gbc = new GridBagConstraints();
imageLabel = new JLabel();
try {
imageLabel.setIcon(new ImageIcon(
new URL("http://pm1.narvii.com/6535/1b362404d09091a335ce53fa68506827418890a3_128.jpg")));
} catch (MalformedURLException e) {
e.printStackTrace();
}
firstName = new JLabel("First Name: ");
lastName = new JLabel("Last Name: ");
level = new JLabel("Level: ");
gender = new JLabel("Gender: ");
pokemonCaught = new JLabel("Pokemon Caught: ");
raidWon = new JLabel("Raid Won: ");
pokestopVisited = new JLabel("Pokestop Visited: ");
nameField = new JTextField(10);
lastNameField = new JTextField(10);
levelField = new JTextField(10);
genderField = new JTextField(10);
pokemonCaughtButton = new JButton("Show");
raidWonButton = new JButton("Show");
pokestopVisitedButton = new JButton("Show");
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 7;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(5, 5, 5, 5);
pane.add(imageLabel, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
pane.add(firstName, gbc);
gbc.gridx = 2;
pane.add(nameField, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(lastName, gbc);
gbc.gridx = 2;
pane.add(lastNameField, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(level, gbc);
gbc.gridx = 2;
pane.add(levelField, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(gender, gbc);
gbc.gridx = 2;
pane.add(genderField, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(pokemonCaught, gbc);
gbc.gridx = 2;
pane.add(pokemonCaughtButton, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(raidWon, gbc);
gbc.gridx = 2;
pane.add(raidWonButton, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(pokestopVisited, gbc);
gbc.gridx = 2;
pane.add(pokestopVisitedButton, gbc);
frame.add(pane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
它产生类似于这个的GUI: