Javaでより大きなGUIに取り組んでおり、レイアウトマネージャーに腹を立てています。
可変数のJComponents(ラベル、ボタン、JSpinners、JSlidersなど)を含む「設定パネル」があります。私は以下が欲しいだけです:
JLabel <-> JComponent
JLabel <-> JComponent
JLabel <-> JComponent
...
パネルのサイズは500pxなので、多くのコンポーネントを配置するのに十分なスペースがあります。残念ながら、すべてのコンポーネントにMaximumSizeを設定しても、GridLayoutは常にコンポーネントのサイズをパネル全体に拡大します。ボタンの高さが250pxのボタンが2つしかない場合は、馬鹿げているように見えます。
フローレイアウトを試してみましたが、改行の仕方がわかりません。 BoxLayout.Y_AXISを試しましたが、コンポーネントが常に中央に配置され、ラベルとコンポーネントが同じ行にありません。
LayoutManagerを使用してこれを適切に処理するための良い方法と短い方法を知っている人はいますか?
他のレイアウトの代わりに、FlowLayoutである別のパネル内に、GridLayoutを使用してパネルを配置することもできます。こうすることで、スペースは損なわれませんが、使用可能なスペース全体に広がることはありません。
本来の目的以外の目的でGridLayoutを使用しないでください。 GridBagLayoutの方がそれよりもMigLayoutのほうが適しているように思えます(ただし、標準のJavaの一部ではないため、最初にダウンロードする必要があります)。それか、すべての行を保持するためのLineLayoutやGridLayoutなどのレイアウトマネージャーを組み合わせる。
たとえば、GridBagLayoutを使用します。
import Java.awt.*;
import javax.swing.*;
public class LayoutEg1 extends JPanel{
private static final int ROWS = 10;
public LayoutEg1() {
setLayout(new GridBagLayout());
for (int i = 0; i < ROWS; i++) {
GridBagConstraints gbc = makeGbc(0, i);
JLabel label = new JLabel("Row Label " + (i + 1));
add(label, gbc);
JPanel panel = new JPanel();
panel.add(new JCheckBox("check box"));
panel.add(new JTextField(10));
panel.add(new JButton("Button"));
panel.setBorder(BorderFactory.createEtchedBorder());
gbc = makeGbc(1, i);
add(panel, gbc);
}
}
private GridBagConstraints makeGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = x;
gbc.weighty = 1.0;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.anchor = (x == 0) ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.HORIZONTAL;
return gbc;
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Layout Eg1");
frame.getContentPane().add(new LayoutEg1());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
Java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
より複雑なレイアウトの場合、私はしばしば GridBagLayout を使用しましたが、これはより複雑ですが、それは価格です。今日、私はおそらくチェックアウトします MiGLayout 。
私のプロジェクトでは、GridLayoutを使用することができ、結果は非常に安定しており、ちらつきがなく、完全に機能する垂直スクロールバーを備えています。
まず、設定用のJPanelを作成しました。私の場合、それは各パラメーターの行と2つの列を持つグリッドです。左の列はラベル用で、右の列はコンポーネント用です。あなたのケースも似ていると思います。
JPanel yourSettingsPanel = new JPanel();
yourSettingsPanel.setLayout(new GridLayout(numberOfParams, 2));
次に、パラメーターを繰り返し、JLabelの追加とコンポーネントの追加を交互に繰り返すことにより、このパネルにデータを追加します。
for (int i = 0; i < numberOfParams; ++i) {
yourSettingsPanel.add(labels[i]);
yourSettingsPanel.add(components[i]);
}
YourSettingsPanelがコンテナー全体に拡張されないようにするために、まずダミーパネルの北の領域でそれをラップします。これをnorthOnlyPanelと呼びます。
JPanel northOnlyPanel = new JPanel();
northOnlyPanel.setLayout(new BorderLayout());
northOnlyPanel.add(yourSettingsPanel, BorderLayout.NORTH);
最後に、northOnlyPanelをJScrollPaneでラップします。
JScrollPane scroll = new JScrollPane(northOnlyPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
ほとんどの場合、JFrame内で拡張されたこのJScrollPaneを表示します。 CENTER領域のBorderLayout JFrameに追加できます。
window.add(scroll, BorderLayout.CENTER);
私の場合は、GridLayout(1、2)パネルの左側の列に配置し、右側の列を使用して各パラメーターのコンテキストヘルプを表示します。
JTextArea help = new JTextArea();
help.setLineWrap(true);
help.setWrapStyleWord(true);
help.setEditable(false);
JPanel split = new JPanel();
split.setLayout(new GridLayout(1, 2));
split.add(scroll);
split.add(help);