java - GUI FlowLayout,锁定所有组件位置

标签 java swing user-interface resize flowlayout

我一直在四处搜索,但找不到任何有关在使用 FlowLayout 时锁定窗口中组件位置的信息。我使用的是 GridLayout,除了不喜欢它的外观之外,我无法调整 JTextArea 的大小。我将窗口上的所有内容都精确地放置在我想要的位置和正确的大小,除非用户调整窗口大小,然后所有内容都会散落各处。

是否有任何方法可以锁定 JTextArea/JButtons/JLabels,以便在用户调整窗口大小时它们不会移动,或者甚至更好地锁定窗口,以便用户无法对其进行调整?

这是我尝试过的:

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

最佳答案

强烈请求与已接受的答案不同,并且我发现了一些问题:

  • 通过锁定设定的大小,您可能会面临在除您自己的平台之外的所有平台(操作系统、显示设置)上显示糟糕的 GUI 的风险。
  • 通过设置 JTextAreas 显示大小,您可以完全防止它在 JScrollPane 中滚动。
  • 通过强制使用相对“愚蠢”的布局管理器 FlowLayout 显示 GUI,您限制了布局选项。
  • 通过设置任何组件的大小,您可以人为地限制其大小,从而阻止布局管理器和组件本身为该平台设置组件的最佳大小。

相反,我建议:

  • 您应该设置 JTextArea 显示的行和列
  • 在 JScrollPane 中显示 JTextArea。
  • 使用更灵活的布局管理器,或者通常更好的布局组合,通常由嵌套 JPanel 使用,每个布局管理器都使用自己的布局管理器。
  • 避免设置大小,而是在添加所有组件后在顶级窗口上调用 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();
         }
      });
   }
}

关于java - GUI FlowLayout,锁定所有组件位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33060237/

相关文章:

java - Gui 的按钮布局问题

Java-数组/字符串混搭错误?

java - 从 eclipse 插件打开操作系统默认文件资源管理器?

java - 如何使用 Java 创建图像?

java - 在 OsmDroid 中获取我的位置不起作用

java - 如何将 JTextField 中的数据传输到 JLabel?

java - 如何从 swing 组件获取类名称?

java - 如何获取java程序中打开的文件的完整文件名和路径?

java - GridBagLayout 和 ScrollPane

c - 在 C 中制作没有框架的 GUI