【问题标题】:Swing - how to mix JTextField and JTextAreas and have same visual appearance?Swing - 如何混合 JTextField 和 JTextAreas 并具有相同的视觉外观?
【发布时间】:2011-02-08 22:37:23
【问题描述】:

我正在使用 miglayout 创建一个表单,其中有 JTextFields(简短的输入答案)以及 JTextAreas(较长的答案)。问题是双重的。

  1. Scrollpane 环绕文本区域周围的边框与文本字段的边框不匹配。
  2. 文本区域/文本字段的宽度和位置不同,导致它们无法正确对齐。

alt text http://grab.by/3O0V

从右/左更改为右/填充后: alt text http://grab.by/3RMk 您可以看到边界对齐,但仍然存在差距。我尝试设置 novisualpadding 但这并没有解决它。

源代码:

package test2;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;

public class Test extends JPanel {

private static final int NUM_CHARACTERS_WIDTH = 20;
private static final int NUM_ROWS = 5;
public Test() {

    setLayout(new MigLayout(
            "wrap 2",
            // Align text labels on the so their right edge meets left edge of the text fields
            "[right][left]"
            ));

    add(new JLabel("Text field:"));
    add(new JTextField(NUM_CHARACTERS_WIDTH));

    add(new JLabel("No scrollpane text area:"));
    add(new JTextArea(NUM_ROWS, NUM_CHARACTERS_WIDTH));

    add(new JLabel("Scrollpane text area:"));
    add(new JScrollPane(new JTextArea(NUM_ROWS, NUM_CHARACTERS_WIDTH)));

    add(new JLabel("Text field:"));
    add(new JTextField(NUM_CHARACTERS_WIDTH));

}


public static void main(String[] args) {
    JFrame frame = new JFrame("");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel panel = new Test();
    frame.add(panel);
    frame.pack();
    frame.setVisible(true);
}

}

混合和匹配 jtextfield 和 jtextareas 的首选方法是什么,同时仍保持视觉和谐?我现在注意到,当焦点在其中时,文本字段周围有一个蓝色突出显示,而不是文本区域......另一个视觉不连续性的来源。

【问题讨论】:

    标签: java user-interface swing miglayout


    【解决方案1】:

    不确定如何解决边框问题,但要解决布局情况,我会使用 springlayout。 Springlayout 只是一种在 JPanel 中更好地布局元素的方法。你可以了解更多关于它Java Sun Tutorial

    具体而言,您可以通过设置每个元素的北、南、西和东边界来使用它。为此,您必须首先将标签调用从添加中取出,以便可以命名每个调用。所以而不是:

    add(new JLabel("Text field:"));
    

    做:

    JLabel myLabelName = new JLabel("Text field:");
    add(myLabelName);
    

    对于每个元素(JLabels、JTextAreas 和 JTextField)。完成此操作后,您可以轻松设置布局。

    Springlayout layout = new SpringLayout();
    setLayout(layout);
    

    然后,您必须为每个元素设置所需的任何边框。它们必须按照特定的顺序南、北、西然后东。尽管如果您不想使用,则不必使用所有四个边框。这是一个关于如何设置第一个文本区域的示例,即顶部的那个。

    layout.putConstraint(SpringLayout.NORTH, FirstTextAreaName, 10, SpringLayout.NORTH, this);
    layout.putConstraint(SpringLayout.WEST, FirstTextAreaName, this.getWidth()/2, SpringLayout.WEST, this);
    layout.putConstraint(SpringLayout.EAST, FirstTextAreaName, -10, SpringLayout.EAST, this);
    

    此示例未设置文本区域的南部,但如果您愿意,它必须是第一个。第一行将文本区域的北侧设置为距顶部 10 个像素。设置其他区域时,您使用前一个(上方)区域名称而不是这个名称,并说它距离前一个区域的南边 10 像素:

    layout.putConstraint(SpringLayout.NORTH, SecondTextAreaName, 10, SpringLayout.SOUTH, FirstTextAreaName);
    

    上面示例中的第二行将文本区域的东侧设置为从主面板的中间开始。最后第三行将文本区域的东侧设置为距主面板东侧 10 个像素。

    【讨论】:

      【解决方案2】:

      对于布局问题,请尝试使用 columnConstraints 值 [right][fill] 而不是 [right][left]。

      对于另一个问题,这似乎是外观不一致。我在 Windows 中运行了您的代码,差异也存在,但不那么明显。我的建议是为文本字段和文本区域明确设置相同的边框。

      setLayout(new MigLayout(
              "wrap 2",
              "[right][fill]"
              ));
      
      JTextField textField;
      JScrollPane scrollPane;
      
      add(new JLabel("Text field:"));
      textField = new JTextField(NUM_CHARACTERS_WIDTH);
      textField.setBorder( new EtchedBorder( EtchedBorder.LOWERED ) );
      add(textField);
      
      add(new JLabel("No scrollpane text area:"));
      add(new JTextArea(NUM_ROWS, NUM_CHARACTERS_WIDTH));
      
      add(new JLabel("Scrollpane text area:"));
      scrollPane = new JScrollPane(new JTextArea(NUM_ROWS, NUM_CHARACTERS_WIDTH));
      scrollPane.setBorder( new EtchedBorder( EtchedBorder.LOWERED ) );
      add(scrollPane);
      
      add(new JLabel("Text field:"));
      textField = new JTextField(NUM_CHARACTERS_WIDTH);
      textField.setBorder( new EtchedBorder( EtchedBorder.LOWERED ) );
      add(textField);
      

      如果您无法让 MigLayout 对齐组件,请考虑使用 java.awt.GridBagLayout:

      import static java.awt.GridBagConstraints.*;
      
      setLayout( new GridBagLayout() );
      
      GridBagConstraints leftCons = new GridBagConstraints();
      leftCons.anchor = NORTHEAST;
      leftCons.fill = NONE;
      leftCons.weightx = 1.0;
      leftCons.gridy = RELATIVE;
      leftCons.gridx = 0;
      leftCons.insets = new Insets( 4, 8, 4, 8 );
      
      GridBagConstraints rightCons = new GridBagConstraints();
      rightCons.anchor = NORTHWEST;
      rightCons.fill = HORIZONTAL;
      rightCons.weightx = 1.0;
      rightCons.gridy = RELATIVE;
      rightCons.gridx = 1;
      rightCons.insets = leftCons.insets;
      
      add(new JLabel("Text field:"), leftCons);
      add(new JTextField(NUM_CHARACTERS_WIDTH), rightCons);
      
      add(new JLabel("No scrollpane text area:"), leftCons);
      add(new JTextArea(NUM_ROWS, NUM_CHARACTERS_WIDTH), rightCons);
      
      add(new JLabel("Scrollpane text area:"), leftCons);
      add(new JScrollPane(new JTextArea(NUM_ROWS, NUM_CHARACTERS_WIDTH)), rightCons);
      
      add(new JLabel("Text field:"), leftCons);
      add(new JTextField(NUM_CHARACTERS_WIDTH), rightCons);
      

      【讨论】:

      • [fill] 有帮助。但是,大小在 Mac OSX 上仍然不完美:grab.by/3O9U
      • 也许更适应的选择是采用一种组件类型的首选边框并将其应用于另一种;例如,textField.setBorder(scrollPane.getBorder())。
      • 考虑试试 java.awt.GridBagLayout。有关更多代码,请参阅我修改后的答案。
      【解决方案3】:

      我知道 MiGLAyout(我喜欢它,顺便说一句)能够对视觉对齐与严格的像素对齐进行特殊处理。你可能会遇到这个......'al'单位标识符用于此,但我不必使用它,因此无法提供示例。可能值得下载 MiG 示例项目,看看它们是否有相同的对齐问题(我确定它们的面板与您的类似)。

      为了它的价值,我们经常在同一个面板中混合文本字段和区域并且不会遇到这种情况......我们确实必须将滚动窗格的边框设置为与 Noel Ang 建议的文本字段的边框相同。

      此外,我们通常在添加每个组件时指定它们,而不是在布局构造函数中指定约束 - 不确定这是否会有所不同...

      【讨论】:

        【解决方案4】:

        首先为屏幕截图 +1。 由于您使用的是 Mac,您是否尝试过 Quaqua Look And Feel?它正确地呈现文本框/区域。

        【讨论】:

          【解决方案5】:

          答案是 MiG Layout 的人是working on a fix for their next version。

          你好,

          Apple 有一个讨厌的习惯,即默认补偿,不让开发人员决定。在这种情况下,他们添加了边框以使其在视觉上更像 OS X。这应该是布局管理器的选择...

          MigLayout 可以补偿这样的视觉边界,但它仅适用于 Windows XP 中的 JTabbedPane。我不确定它可以在 OS X 中 100% 完成。我得检查一下。我们不希望文本字段增长到边界。

          我已将此添加到下一个版本的待办事项列表中。

          【讨论】:

            【解决方案6】:

            我知道这个问题已经很老了,但是要让TextArea 的边框与TextField 的边框相匹配:

            (myTextArea).setBorder(new JTextField().getBorder());
            

            这应该给你的TextArea 加上一个边框,就像TextField 周围的那个一样。

            【讨论】:

            • 不错的一个!但应该是“new JTextField().getBorder()”
            猜你喜欢
            • 2012-08-27
            • 1970-01-01
            • 2011-02-05
            • 1970-01-01
            • 1970-01-01
            • 2022-01-15
            • 2016-09-03
            • 1970-01-01
            相关资源
            最近更新 更多