2010-04-16 44 views
7

我正在使用miglayout來創建一個表單,其中有JTextFields(短輸入答案)以及JTextAreas(更長的答案)。問題是雙重的。Swing - 如何混合JTextField和JTextAreas並具有相同的視覺外觀?

  1. 圍繞Scrollpane包裹的文本區域放置的邊框與文本區域的邊框不匹配。
  2. textarea/textfield的寬度和位置不同,導致它們不能正確排列。

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,同時仍保持視覺上的和諧?現在我注意到,當焦點位於其中時,文本字段在其周圍具有藍色高光,與文本區域相反......視覺不連續性的另一個來源。

回答

0

答案是米格佈局人員是working on a fix for their next version

你好,

蘋果在默認情況下的補償,而不是讓開發商決定的一個討厭的習慣中。在這種情況下,他們添加了一個邊框,使其更像視覺化的OS X.這應該是佈局管理器的選擇...

MigLayout可以補償這樣的視覺邊界,但它只是爲了JTabbedPane在Windows XP中。我不確定它在OS X中可以完成100%。我必須檢查。我們不希望文本字段只是增長到邊界。

我已將此添加到下一個版本的待辦事項列表中。

3

不知道你如何解決你的邊界問題,但要解決你的佈局情況,我只會使用springlayout。 Springlayout只是一種更好地在JPanel中佈局元素的方法。您可以瞭解更多關於它的信息Java Sun Tutorial

具體來說,您可以通過設置每個元素的北,南,西,東邊界的位置來使用它。要做到這一點,您必須首先將標籤調用從添加中移出,以便每個都可以被命名。因此,而不是:

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

務必:

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

對於每一個元素(Jlabel之下,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); 

Identicial borders http://img412.imageshack.us/img412/6341/clipboard01jl.png

如果你不能得到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); 
+0

[填充]有幫助。但是,Mac OSX上的尺寸仍然不夠完美:http://grab.by/3O9U – I82Much 2010-04-16 18:57:01

+1

也許更適應性的選擇是採用一種組件類型的首選邊框並將其應用於另一種;例如textField.setBorder(scrollPane.getBorder())。 – 2010-04-16 18:57:07

+0

考慮給java.awt.GridBagLayout一個嘗試。有關更多代碼,請參閱我的修訂答案 – 2010-04-16 19:16:53

2

我知道MiGLAyout(我的愛,BTW)有能力對視覺對齊和嚴格的像素對齊進行特殊處理。你可能會遇到這個...'al'單元標識符用於這個,但我沒有必要使用它,所以不能提供示例。這可能是值得下載米格示例項目,看看他們是否有相同的路線問題(我敢肯定他們有面板類似於你的)。我們必須設置滾動窗格的邊界是相同的Noel Ang建議的文本字段的邊界。

此外,而不是在佈局構造特定的約束,我們通常會給出他們,因爲我們添加的每個組件 - 不知道是否有差別或不...

0

首先+1的屏幕截圖。 既然您使用Mac,您是否嘗試過Quaqua Look and Feel?它正確地呈現文本框/區域。

4

我知道這個問題是很老,但要獲得邊框的TextArea相匹配的TextField

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

這應該給一個邊界你TextAreaTextField圍繞一個。

+0

不錯的一個!但它應該是「新的JTextField()。getBorder()」 – 2016-08-31 08:37:33