Java(1.8)Swingで新しいGUIを作成しています。すべてのコンポーネントのサイズ変更動作をオーバーライドする方法を探しています。
編集した写真をいくつか説明します。
これは、3つのパネルとJToolBar
を備えた私のフルスクリーンGUIです。緑色のものは固定サイズである必要があり、その他はサイズ変更可能です。
現在、それらを整理するための小さなGridLayout
が2つしかありません(1つは垂直、1つは緑とシアンのパネル用です)。
たとえば、右側からフレームサイズを小さくする場合、新しいフレームサイズに合わせて、青とシアンのパネルをサイズ変更済みにする必要があります。しかし、緑のパネルはfixedでなければなりません。 (私が思うに最も難しい部分ではありません。)
これは私にとって最も難しい部分です。シアン(または青)パネルのリーチが最小サイズになるとすぐに、フレームから消えても、左にある緑のパネルを「Push」にしたい.
もちろん、フレームを右に引くと、緑色のパネルが再び表示されます。
どうすればいいですか?
JSplitPane
または特定のリスナーを使用して、サイズ変更の動作を手動で決定することを考えましたが、いくつかのアドバイスが必要です。
既存の投稿がこれに答えることができる場合は申し訳ありませんが、私にとって問題を説明する答えは見つかりませんでした。
前もって感謝します!
他の例が必要な場合は、同じように動作する「Evernote」ソフトウェアをご覧ください
Green
パネルの最大/最小/優先サイズを設定すると、最初の条件下でそのパネルを同じサイズに保つことができます。サイズ変更を確認するには、他のComponentListener
のいずれかでJPanel
を使用します-サイズが特定の幅を下回る場合は、Green
パネル。
以下は、これを行うためのハッキングされた例です。Green
が600未満の場合、Blue
パネルのサイズを変更し、サイズ変更は加重サイズ変更(全幅の30%)です。真のL&Fを取得し、希望するものを得るには、レイアウト/サイズを調整する必要があります。
import Java.awt.BorderLayout;
import Java.awt.Color;
import Java.awt.Dimension;
import Java.awt.GridBagConstraints;
import Java.awt.GridBagLayout;
import Java.awt.GridLayout;
import Java.awt.Insets;
import Java.awt.Rectangle;
import Java.awt.event.ComponentAdapter;
import Java.awt.event.ComponentEvent;
import Java.awt.event.ComponentListener;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
public class GridTest extends JPanel{
private boolean changeAllowed = false;
//keep reference to cyan for the height dimension
final JPanel cyan = new JPanel();
public GridTest(){
cyan.setPreferredSize(new Dimension(600, 300));//provide sizing hint
}
private Dimension getCustomDimensions(){
if ( changeAllowed ){
return new Dimension((int)(super.getParent().getBounds().width * 0.3), cyan.getBounds().height);
}else{
return new Dimension(200, cyan.getBounds().height);
}
}
@Override
public Dimension getMaximumSize(){
return getCustomDimensions();
}
@Override
public Dimension getMinimumSize(){
return getCustomDimensions();
}
@Override
public Dimension getPreferredSize(){
return getCustomDimensions();
}
public static void main(String[] args) throws Exception{
SwingUtilities.invokeAndWait(new Runnable(){
@Override
public void run() {
final int MINIMUM = 600;
JFrame frame = new JFrame();
frame.add(new JToolBar(), BorderLayout.NORTH);
final JPanel blue = new JPanel();
final GridTest green = new GridTest();
green.setBackground(Color.green);
green.setOpaque(true);
green.cyan.setBackground(Color.cyan);
green.cyan.setOpaque(true);
blue.setOpaque(true);
blue.setBackground(Color.blue);
blue.setPreferredSize(new Dimension(900, 300));//hint at size
blue.setMinimumSize(new Dimension(100, 200));//hint at size
//Nest Box Layouts
Box top = Box.createHorizontalBox();
top.add(blue);
Box bottom = Box.createHorizontalBox();
bottom.add(green);
bottom.add(green.cyan);
Box vert = Box.createVerticalBox();
vert.add(top);
vert.add(bottom);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(vert);
//listen for resizes
blue.addComponentListener(new ComponentAdapter(){
@Override
public void componentResized(ComponentEvent e) {
if ( blue.getBounds().width < MINIMUM ){//set flag
green.changeAllowed = true;
}else{
green.changeAllowed = false;
}
}
});
frame.pack();
frame.setSize(800, 600);
frame.setVisible(true);
}
});
}
}
BoxLayout
を使用して、緑とシアンのパネルを含めることができます。 BoxLayout
は、コンポーネントの最小サイズと最大サイズを尊重します。したがって、緑のパネルでは最大サイズを優先サイズに設定し、シアンのパネルでは最小サイズを優先サイズに設定します。
_import Java.awt.*;
import Java.util.*;
import javax.swing.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
JPanel blue = new JPanel();
blue.setBackground( Color.BLUE );
blue.setPreferredSize( new Dimension(500, 100) );
Box box = Box.createHorizontalBox();
JPanel green = new JPanel();
green.setBackground( Color.GREEN );
green.setPreferredSize( new Dimension(200, 100) );
green.setMaximumSize( green.getPreferredSize() );
box.add( green );
JPanel cyan = new JPanel();
cyan.setBackground( Color.CYAN );
cyan.setPreferredSize( new Dimension(300, 100) );
cyan.setMinimumSize( cyan.getPreferredSize() );
box.add( cyan );
setLayout( new BorderLayout() );
add(blue, BorderLayout.NORTH);
add(box, BorderLayout.CENTER);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
_
もちろん、適切な解決策は、各パネルのgetMaximumSize()
およびgetMinimumSize()
メソッドをオーバーライドして、パネルの希望のサイズを返すことです。
これは私がそれを行う方法であり、これが適切な方法であるかどうかはわかりません:
最初にレイアウトをnullに設定します。
次に、フレームのコンポーネントサイズ変更イベントを作成します。
addComponentListener(new ComponentAdapter(){
public void componentResized(ComponentEvent e){
}
});
ここでは、コンポーネントのサイズを変更するときに、コンポーネントを手動で変更できます。私はいくつかのプログラムでこれを行って、フレームの左右のスクロールペインを常に同じ幅に保ち、他のすべてのサイズをサイズ変更に合わせて上下させました。
これは、緑とシアンのコンポーネントに適切な最小サイズを設定すれば、GridBagLayoutで簡単になります。
setLayout(new GridBagLayout());
green.setMnimumSize(new Dimension(0, 0));
cyan.setMinimumSize(new Dimension(100, 100)); // whatever fits
add(blue, new GridBagConstraints(0, 0, 2, 1,
1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0);
add(green, new GridBagConstraints(0, 1, 1, 1,
0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0);
add(cyan, new GridBagConstraints(1, 1, 1, 1,
1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0);
シアンとブルーのコンポーネントにウェイトxを指定し、resize = HORIZONTALを設定すると、コンテナに合わせてサイズが変更されます。
重要なシーケンスは次のとおりです。
frame.revalidate();
frame.pack();
frame.repaint();
一連の各変更の後にこのシーケンスを使用します。コードを実行し、画面に表示される結果を確認します。
Java.awt.GridBagLayoutとJava.awt.GridBagConstraintsの組み合わせが好きで、コンテンツペインから起動するすべてのコンテナでこのレイアウトを使用しています。
コンテナを他のコンテナに追加する場合は、それぞれのコンテナでレイアウトを使用します。そうしないと、階層にレイアウトがないため計算が失敗します。