GUI FlowLayout,锁定所有组件位置
GUI FlowLayout, lock all components position
我一直在搜索,但找不到任何有关在使用 FlowLayout
时锁定 window 中组件位置的信息。我在使用 GridLayout
,除了不喜欢它的外观,我无法调整 JTextArea
的大小。我把 window 上的所有内容都放在我想要的位置和正确的大小,除非用户调整 window 的大小,然后一切都乱七八糟。
有什么方法可以锁定 JTextArea/JButtons/JLabels 所以如果用户调整 window 的大小他们不会移动,或者最好锁定 window 所以用户不能调整?
这是我尝试过的方法:
public class CopyFile extends JFrame{
private JFileChooser fc;
private JButton copyButton;
private JButton chooseFileButton;
private JButton destinationButton;
private File workingDirectory;
private JLabel sourceLabel;
private JTextArea displayCopyText;
private JLabel destinationLabel;
private JTextField sourceText;
private JLabel copyText;
private JTextField destinationText;
public static void main(String [] args) {
CopyFile go = new CopyFile();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setSize(500, 150);
go.setVisible(true);
}
public CopyFile() {
super("Copy a text file");
setLayout(new FlowLayout());
fc = new JFileChooser();
//Open dialog box inside project folder to make easier to find files
workingDirectory = new File(System.getProperty("user.dir"));
fc.setCurrentDirectory(workingDirectory);
//create labels and buttons for window
chooseFileButton = new JButton("CHOOSE SOURCE FILE");
destinationButton = new JButton("DESTINATION FOLDER");
copyButton = new JButton("COPY FILE");
sourceLabel = new JLabel("SOURCE FILE: ", JLabel.CENTER);
sourceText = new JTextField(15);
sourceText.setEditable(false);
destinationText = new JTextField(15);
destinationText.setEditable(false);
destinationLabel = new JLabel("DESTINATION:", JLabel.CENTER);
//JScrollPane SP = new JScrollPane();
displayCopyText = new JTextArea();
displayCopyText.setPreferredSize(new Dimension(300, 50));
displayCopyText.setRows(2);
displayCopyText.setLineWrap(true);
displayCopyText.setWrapStyleWord(true);
displayCopyText.setEditable(false);
//add everything to JFrame
add(sourceLabel);
add(sourceText);
add(chooseFileButton);
add(destinationLabel);
add(destinationText);
add(destinationButton);
//add(copyText);
add(displayCopyText);
add(copyButton);
//Create TheHandler object to add action listeners for the buttons.
TheHandler handler = new TheHandler();
chooseFileButton.addActionListener(handler);
destinationButton.addActionListener(handler);
copyButton.addActionListener(handler);
}
//Inner class to create action listeners
private class TheHandler implements ActionListener {
private File selectedDestinationFile;
private File selectedSourceFile;
private int returnVal;
public void actionPerformed(ActionEvent event) {
//Selecting a source file and displaying what the user is doing.
if(event.getSource() == chooseFileButton) {
returnVal = fc.showOpenDialog(null);
//Set the path for the source file.
if(returnVal == JFileChooser.APPROVE_OPTION) {
selectedSourceFile = fc.getSelectedFile();
sourceText.setText(selectedSourceFile.getName());
}
}//end if
//Handle destination button.
if(event.getSource() == destinationButton) {
returnVal = fc.showSaveDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION) {
selectedDestinationFile = fc.getSelectedFile();
destinationText.setText(fc.getSelectedFile().getAbsolutePath());
}
}//end if
//Handle copy button
if(event.getSource() == copyButton) {
Path sourcePath = selectedSourceFile.toPath();
Path destinationPath = selectedDestinationFile.toPath();
try {
Files.copy(sourcePath, destinationPath);
} catch (IOException e) {
e.printStackTrace();
}
if(returnVal == JFileChooser.APPROVE_OPTION) {
displayCopyText.append("SUCCESSFULLY COPIED:\n"
+ selectedDestinationFile.getName());
}
else {
displayCopyText.append("COPY WAS CANCELED BY USER.\n");
}
}//end if
}//end actionPerformed
}//end TheHandler class
}//end class
您可以使用 JFrame::setResizable(false)
来锁定正在调整大小的 window。
所以你的代码可能是这样的
public static void main(String[] args) {
CopyFile go = new CopyFile();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setResizable(false); //No resize is possible
go.setSize(500, 150);
go.setVisible(true);
}
这可能会解决您的问题
使用固定大小是一个非常非常糟糕的主意。尝试使用更灵活的布局可能是布局的组合来实现你的目标。关于布局管理器,请参阅 here。
尝试遵循 of Hovercraft .
我强烈不同意接受的答案,我看到了一些问题:
- 通过锁定设置大小,您可能会在所有平台(OS、显示设置)中显示糟糕的 GUI,而不是您自己的平台。
- 通过设置 JTextAreas 的显示大小,您可以完全防止它在 JScrollPane 中滚动。
- 通过强制使用相对 "dumb" 布局管理器 FlowLayout 显示 GUI,您限制了布局选项。
- 通过设置任何组件的大小,您可以人为地限制其大小,从而阻止布局管理器和组件本身为该平台的组件设置最佳大小。
相反,我建议:
- 相反,您应该设置 JTextArea 的显示行和列
- 在 JScrollPane 中显示 JTextArea。
- 使用更灵活的布局管理器,或者通常更好的布局组合,通常由嵌套 JPanel 使用,每个布局管理器都使用自己的布局管理器。
- 避免设置大小,而是在添加所有组件后在顶层 window 上调用
pack()
,从而让布局和组件自行调整大小。
例如:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
@SuppressWarnings("serial")
public class CopyFile2 extends JPanel {
private static final int ROWS = 3;
private static final int COLS = 20;
private static final int GBC_I = 4;
private static final Insets INSETS = new Insets(GBC_I, GBC_I, GBC_I, GBC_I);
private JTextField sourceField = new JTextField(10);
private JTextField destField = new JTextField(10);
private JTextArea displayCopyText = new JTextArea(ROWS, COLS);
public CopyFile2() {
setLayout(new GridBagLayout());
add(new JLabel("Source File:"), createGbc(0, 0));
add(sourceField, createGbc(1, 0));
add(new JButton("Choose Source File"), createGbc(2, 0));
add(new JLabel("Destination:"), createGbc(0, 1));
add(destField, createGbc(1, 1));
add(new JButton("Destination Folder"), createGbc(2, 1));
GridBagConstraints gbc = createGbc(0, 2);
gbc.gridwidth = 2;
add(new JScrollPane(displayCopyText), gbc);
add(new JButton("Copy File"), createGbc(2, 2));
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = INSETS;
return gbc;
}
private static void createAndShowGUI() {
CopyFile2 paintEg = new CopyFile2();
JFrame frame = new JFrame("CopyFile2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(paintEg);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
我一直在搜索,但找不到任何有关在使用 FlowLayout
时锁定 window 中组件位置的信息。我在使用 GridLayout
,除了不喜欢它的外观,我无法调整 JTextArea
的大小。我把 window 上的所有内容都放在我想要的位置和正确的大小,除非用户调整 window 的大小,然后一切都乱七八糟。
有什么方法可以锁定 JTextArea/JButtons/JLabels 所以如果用户调整 window 的大小他们不会移动,或者最好锁定 window 所以用户不能调整?
这是我尝试过的方法:
public class CopyFile extends JFrame{
private JFileChooser fc;
private JButton copyButton;
private JButton chooseFileButton;
private JButton destinationButton;
private File workingDirectory;
private JLabel sourceLabel;
private JTextArea displayCopyText;
private JLabel destinationLabel;
private JTextField sourceText;
private JLabel copyText;
private JTextField destinationText;
public static void main(String [] args) {
CopyFile go = new CopyFile();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setSize(500, 150);
go.setVisible(true);
}
public CopyFile() {
super("Copy a text file");
setLayout(new FlowLayout());
fc = new JFileChooser();
//Open dialog box inside project folder to make easier to find files
workingDirectory = new File(System.getProperty("user.dir"));
fc.setCurrentDirectory(workingDirectory);
//create labels and buttons for window
chooseFileButton = new JButton("CHOOSE SOURCE FILE");
destinationButton = new JButton("DESTINATION FOLDER");
copyButton = new JButton("COPY FILE");
sourceLabel = new JLabel("SOURCE FILE: ", JLabel.CENTER);
sourceText = new JTextField(15);
sourceText.setEditable(false);
destinationText = new JTextField(15);
destinationText.setEditable(false);
destinationLabel = new JLabel("DESTINATION:", JLabel.CENTER);
//JScrollPane SP = new JScrollPane();
displayCopyText = new JTextArea();
displayCopyText.setPreferredSize(new Dimension(300, 50));
displayCopyText.setRows(2);
displayCopyText.setLineWrap(true);
displayCopyText.setWrapStyleWord(true);
displayCopyText.setEditable(false);
//add everything to JFrame
add(sourceLabel);
add(sourceText);
add(chooseFileButton);
add(destinationLabel);
add(destinationText);
add(destinationButton);
//add(copyText);
add(displayCopyText);
add(copyButton);
//Create TheHandler object to add action listeners for the buttons.
TheHandler handler = new TheHandler();
chooseFileButton.addActionListener(handler);
destinationButton.addActionListener(handler);
copyButton.addActionListener(handler);
}
//Inner class to create action listeners
private class TheHandler implements ActionListener {
private File selectedDestinationFile;
private File selectedSourceFile;
private int returnVal;
public void actionPerformed(ActionEvent event) {
//Selecting a source file and displaying what the user is doing.
if(event.getSource() == chooseFileButton) {
returnVal = fc.showOpenDialog(null);
//Set the path for the source file.
if(returnVal == JFileChooser.APPROVE_OPTION) {
selectedSourceFile = fc.getSelectedFile();
sourceText.setText(selectedSourceFile.getName());
}
}//end if
//Handle destination button.
if(event.getSource() == destinationButton) {
returnVal = fc.showSaveDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION) {
selectedDestinationFile = fc.getSelectedFile();
destinationText.setText(fc.getSelectedFile().getAbsolutePath());
}
}//end if
//Handle copy button
if(event.getSource() == copyButton) {
Path sourcePath = selectedSourceFile.toPath();
Path destinationPath = selectedDestinationFile.toPath();
try {
Files.copy(sourcePath, destinationPath);
} catch (IOException e) {
e.printStackTrace();
}
if(returnVal == JFileChooser.APPROVE_OPTION) {
displayCopyText.append("SUCCESSFULLY COPIED:\n"
+ selectedDestinationFile.getName());
}
else {
displayCopyText.append("COPY WAS CANCELED BY USER.\n");
}
}//end if
}//end actionPerformed
}//end TheHandler class
}//end class
您可以使用 JFrame::setResizable(false)
来锁定正在调整大小的 window。
所以你的代码可能是这样的
public static void main(String[] args) {
CopyFile go = new CopyFile();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setResizable(false); //No resize is possible
go.setSize(500, 150);
go.setVisible(true);
}
这可能会解决您的问题
使用固定大小是一个非常非常糟糕的主意。尝试使用更灵活的布局可能是布局的组合来实现你的目标。关于布局管理器,请参阅 here。
尝试遵循
我强烈不同意接受的答案,我看到了一些问题:
- 通过锁定设置大小,您可能会在所有平台(OS、显示设置)中显示糟糕的 GUI,而不是您自己的平台。
- 通过设置 JTextAreas 的显示大小,您可以完全防止它在 JScrollPane 中滚动。
- 通过强制使用相对 "dumb" 布局管理器 FlowLayout 显示 GUI,您限制了布局选项。
- 通过设置任何组件的大小,您可以人为地限制其大小,从而阻止布局管理器和组件本身为该平台的组件设置最佳大小。
相反,我建议:
- 相反,您应该设置 JTextArea 的显示行和列
- 在 JScrollPane 中显示 JTextArea。
- 使用更灵活的布局管理器,或者通常更好的布局组合,通常由嵌套 JPanel 使用,每个布局管理器都使用自己的布局管理器。
- 避免设置大小,而是在添加所有组件后在顶层 window 上调用
pack()
,从而让布局和组件自行调整大小。
例如:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
@SuppressWarnings("serial")
public class CopyFile2 extends JPanel {
private static final int ROWS = 3;
private static final int COLS = 20;
private static final int GBC_I = 4;
private static final Insets INSETS = new Insets(GBC_I, GBC_I, GBC_I, GBC_I);
private JTextField sourceField = new JTextField(10);
private JTextField destField = new JTextField(10);
private JTextArea displayCopyText = new JTextArea(ROWS, COLS);
public CopyFile2() {
setLayout(new GridBagLayout());
add(new JLabel("Source File:"), createGbc(0, 0));
add(sourceField, createGbc(1, 0));
add(new JButton("Choose Source File"), createGbc(2, 0));
add(new JLabel("Destination:"), createGbc(0, 1));
add(destField, createGbc(1, 1));
add(new JButton("Destination Folder"), createGbc(2, 1));
GridBagConstraints gbc = createGbc(0, 2);
gbc.gridwidth = 2;
add(new JScrollPane(displayCopyText), gbc);
add(new JButton("Copy File"), createGbc(2, 2));
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = INSETS;
return gbc;
}
private static void createAndShowGUI() {
CopyFile2 paintEg = new CopyFile2();
JFrame frame = new JFrame("CopyFile2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(paintEg);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}