问题
Please have a look at the following code
WizardPanel
package wizardGUI;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class WizardPanel extends JDialog
{
private JPanel cardPanel, buttonPanel;
private JButton next,previous;
private CardLayout c1;
private FileSelector fileSelector;
private DelemeterSelector delemeterSelector;
private int count = 1;
public WizardPanel()
{
//Intializing instance variables
fileSelector = FileSelector.getInstance();
delemeterSelector = DelemeterSelector.getInstance();
cardPanel = new JPanel();
c1 = new CardLayout();
cardPanel.setLayout(c1);
cardPanel.add(fileSelector,"1");
cardPanel.add(delemeterSelector,"2");
c1.show(cardPanel, "1");;
buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
next = new JButton("Next");
next.addActionListener(new NextButtonAction());
previous = new JButton("Previous");
buttonPanel.add(next);
buttonPanel.add(previous);
//Creating the GUI
this.setLayout(new BorderLayout());
this.add(cardPanel,"Center");
this.add(buttonPanel,"South");
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setResizable(true);
this.pack();
this.setVisible(true);
}
private class NextButtonAction implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
c1.show(cardPanel, "2");
}
}
}
FileSelector
package wizardGUI;
/*This is the first panel is wazard GUI. Using this window user can select the correct file
which contains the data required to create the table
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FileSelector extends JPanel
{
private JLabel fileName, description;
private JTextField fileTxt;
private JButton browse;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private static FileSelector instance = null;
private FileSelector()
{
//Intializing instance variables
fileName = new JLabel("File Name: ");
description = new JLabel("Specify the source of the data");
fileTxt = new JTextField(10);
browse = new JButton("Browse");
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
//Creating GUI
this.setLayout(gbl);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.BOTH;
this.add(description,gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(0,10,0,0);
this.add(locationPanel(),gbc);
this.setBorder(BorderFactory.createEmptyBorder());
}
private JPanel locationPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(fileName);
panel.add(fileTxt);
panel.add(browse);
return panel;
}
public static FileSelector getInstance()
{
if(instance==null)
{
instance = new FileSelector();
}
return instance;
}
}
DelemeterSelector
/*This is the second windows in wizard
This class is designed to let the user to select the delemeter to break information */
package wizardGUI;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class DelemeterSelector extends JPanel
{
private JLabel description;
private JRadioButton tabBtn, semicolanBtn, commaBtn, spaceBtn;
private JTextArea txtArea;
private JScrollPane scroll;
private ButtonGroup btnGroup;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private static DelemeterSelector instance = null;
private DelemeterSelector()
{
//Initializing instance variables
description = new JLabel("What delemeter separates your fields? Select the appropreiate delemeter");
tabBtn = new JRadioButton("Tab");
semicolanBtn = new JRadioButton("Semicolan");
commaBtn = new JRadioButton("Comma");
spaceBtn = new JRadioButton("Space");
btnGroup = new ButtonGroup();
btnGroup.add(tabBtn);
btnGroup.add(semicolanBtn);
btnGroup.add(commaBtn);
btnGroup.add(spaceBtn);
txtArea = new JTextArea(20,70);
scroll = new JScrollPane(txtArea);
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
this.setLayout(gbl);
//Creating the GUI
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20,0,0,0);
this.add(description,gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20,0,0,0);
this.add(radioPanel(),gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.insets = new Insets(10,0,0,0);
gbc.fill = GridBagConstraints.BOTH;
this.add(scroll,gbc);
}
private JPanel radioPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(tabBtn);
panel.add(semicolanBtn);
panel.add(commaBtn);
panel.add(spaceBtn);
panel.setBorder(BorderFactory.createTitledBorder("Choose the Delimeter that seperates your fields"));
return panel;
}
public static DelemeterSelector getInstance()
{
if(instance == null)
{
instance = new DelemeterSelector();
}
return instance;
}
}
When I run the code, the "FileSelector" looks really ugly. I want everything to be appear at the top of the pane, but instead, everything appears in middle!! I have even tried GridBagLayout
options to make it resizable, it also failed. The look of it is in the attached image
How can I make it look nice and scalable? Please help
回答1:
Just a quick example which shows the same behavior and a fix, without the need for all that external code (an SSCCE)
import javax.swing.*;
import java.awt.*;
public class CardLayoutDemo {
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame( "TestFrame" );
CardLayout cardLayout = new CardLayout();
JPanel contentPane = new JPanel( cardLayout );
JPanel firstPanel = new JPanel( );
firstPanel.setLayout( new BorderLayout( ) );
firstPanel.add( new JLabel( "Contents" ) );
//wrap the smallest panel instead of directly adding it
contentPane.add( firstPanel, "first" );
// JPanel wrappedPanel = new JPanel( new BorderLayout( ) );
// wrappedPanel.add( firstPanel, BorderLayout.NORTH );
// contentPane.add( wrappedPanel, "first" );
JPanel secondPanel = new JPanel( new BorderLayout( ) );
secondPanel.add( new JComponent() {
@Override
public Dimension getPreferredSize() {
return new Dimension( 500, 500 );
}
}, BorderLayout.CENTER );
contentPane.add( secondPanel, "second" );
cardLayout.show( contentPane, "first" );
frame.setContentPane( contentPane );
frame.pack();
frame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
frame.setVisible( true );
}
} );
}
}
When you run the code without making changes, it will show you a panel where the contents is centered (the firstPanel
). Without making any changes to the firstPanel
, but simply by wrapping it you can keep it at the top. Just replace the contentPane.add( firstPanel, "first" )
by the 3 lines (in comment) underneath.
There are a lot of times where nesting layouts makes it easier to get the desired result, and imo this is one of them.
回答2:
The fill
constraints are not necessary in this case. Also, gridx
and gridy
start from 0. This sample code
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10,0,0,0);
this.add(description,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weighty = 1;
gbc.insets = new Insets(0,10,0,0);
this.add(locationPanel(),gbc);
produces this
Not sure if this is what you want though.
来源:https://stackoverflow.com/questions/13496874/issues-in-locating-elements-and-re-sizing