【问题标题】:Layout with fixed height and variable width JButtons具有固定高度和可变宽度的 JButton 布局
【发布时间】:2011-09-28 20:41:48
【问题描述】:

我寻找一个具有固定高度的 JButtons 的 LayoutManager,JButtons 在宽度上扩展以适应其容器的大小。在 JButtons 上方应该有一个 JLabel 本身,在“选择文件:”的行上。这旨在作为 JFileChooser 的附件,让用户选择最近的文件。我无法让它看起来很正确,我尝试过使用多个 JPanel 和 LayoutManager,例如 BoxLayout。使用 BoxLayout 时,JButtons 仅扩展至必须包含其文本的范围;但我希望所有 JButton 的宽度都相同,这样它们看起来就不好笑了。

注意:我还使用了其他 LayoutManager,例如 Border 和 GridLayout,但它们大多忽略了我的尺寸设置,并且看起来不够复杂。我必须手动完成,Netbeans 等不是一个选项。

工作示例,但视觉上不正确

import java.awt.Color;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class Chooser extends JPanel {


    public Chooser(){
        this.setLayout(new GridLayout(0,1));

        JPanel labelPanel = new JPanel();
        JLabel label = new JLabel("Choose a file:");
        labelPanel.add(label);
        labelPanel.setBackground(Color.red);

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(new JButton("long pathname to a file goes here"));
        buttonPanel.setBackground(Color.blue);

        this.add(labelPanel);
        this.add(buttonPanel);
    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Chooser c = new Chooser();
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setAccessory(c);
        fileChooser.showOpenDialog(null);
    }

}

【问题讨论】:

  • 为什么不通过一个最小但足够的例子向我们展示您的最佳尝试,sscce
  • @Hovercraft 然后我不妨复制粘贴任何 Swing JPanel 代码的随机示例,因为我已经尝试了很多不同的东西。一个工作但视觉上不正确的 BoxLayout 的例子有什么用?证明我试过了?
  • 不,我相信您已经尝试过了,但是如果您发布 SSCCE,我们将了解您的代码和问题的当前结构并更好地了解您的问题,如果我们更好地理解它,我们会更好地帮助您。如果我们修改你的代码示例,你会更好地理解我们的代码。坦率地说,这将节省我们的时间,并使我们更容易为您提供帮助,因为您将为我们的代码提供初始框架。但是,这取决于您自己解决的问题。
  • 不,它会让读者了解你想要什么,它会让你有机会获得关于你的方法的反馈。参见A Visual Guide to Layout Managers,特别是How to Use BoxLayout: Specifying Component Sizes
  • @KyleM as well copy paste any random example of Swing 那么我认为您在错误的论坛上发布了您的问题

标签: java swing layout-manager


【解决方案1】:

如果 GridLayout 嵌套在 BorderLayout 中(实际上是在 JScrollPane 中)呢?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Chooser extends JPanel {
   private static final String[] BUTTON_TEXTS = { "Hello", "Goodbye",
         "Hello Goodbye", "Adios", "This is a long String for WTF" };

   public Chooser() {
      this.setLayout(new BorderLayout());

      JPanel labelPanel = new JPanel();
      JLabel label = new JLabel("Choose a file:");
      labelPanel.add(label);
      labelPanel.setBackground(Color.red);

      JPanel buttonPanel = new JPanel(new GridLayout(0, 1));
      for (int i = 0; i < BUTTON_TEXTS.length; i++) {
         buttonPanel.add(new JButton(BUTTON_TEXTS[i]));
      }
      buttonPanel.add(Box.createVerticalGlue()); // to pad the bottom if needed
      buttonPanel.setBackground(Color.blue);

      this.add(labelPanel, BorderLayout.PAGE_START);
      this.add(new JScrollPane(buttonPanel), BorderLayout.CENTER);
   }

   public static void main(String[] args) {
      Chooser c = new Chooser();
      JFileChooser fileChooser = new JFileChooser();
      fileChooser.setAccessory(c);
      fileChooser.showOpenDialog(null);
   }

}

示例 2 有一个简单的 JList,将其选择放在文件选择器中:

import java.awt.*;
import java.io.File;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Chooser extends JPanel {
   private static final String[] BUTTON_TEXTS = { "Hello", "Goodbye",
         "Hello Goodbye", "Adios", "This is a long String for WTF", "Hello",
         "Goodbye", "Hello Goodbye", "Adios", "This is a long String for WTF" };

   public Chooser(final JFileChooser fileChooser) {
      setLayout(new BorderLayout());

      JPanel labelPanel = new JPanel();
      JLabel label = new JLabel("Choose a file:");
      labelPanel.add(label);
      labelPanel.setBackground(Color.red);

      final JList list = new JList(BUTTON_TEXTS);
      list.addListSelectionListener(new ListSelectionListener() {
         public void valueChanged(ListSelectionEvent e) {
            String selectedString = list.getSelectedValue().toString();
            fileChooser.setSelectedFile(new File(selectedString));
         }
      });

      add(labelPanel, BorderLayout.PAGE_START);
      add(new JScrollPane(list), BorderLayout.CENTER);
   }

   public static void main(String[] args) {
      JFileChooser fileChooser = new JFileChooser();
      Chooser c = new Chooser(fileChooser);
      fileChooser.setAccessory(c);
      fileChooser.showOpenDialog(null);
   }

}

【讨论】:

  • 非常感谢。这是一个很好的起点。就个人而言,我认为 JList 在 JFileChooser 中看起来很有趣,但我可能会为每个 JListItem 添加一个图标(无论它们叫​​什么),然后看看它的外观。
  • @KyleM:注意编辑第二个程序,允许 JList 将其选择放在 JFileChooser 的文本字段中。
  • 谢谢,感激不尽。我确实已经开始工作了。事实上,我所有的功能都可以正常工作,显然我只是在布局上很糟糕。我仍在试图弄清楚 JFileChooser 如何在内部列出其文件(以便我可以模仿),但到目前为止我也坚持这一点,涉足源代码。
  • @Hovercraft Full Of Eels 我对你有很大的问题(JList 和鼠标)示例,将作为我的问题 +1 被问(稍后)
  • 没关系,正在考虑另一个问题。再次感谢你的帮助。标记为答案。