Related
We are making a project in OpenGL using lwjgl3. Our application has a button 'Add Cube' which opens a new JFrame containing 4 JTextFields and 2 JButtons, the layout for this JFrame is made using GroupLayout. My friends who are running our project on Windows/Linux can select and edit these JTextFields without any problem, yet me, using MacOS High Sierra, can't.
When I open the JFrame none of the textfields are selected, they do register clicks (textField.setText when mouse clicked works), but they never grab focus, the flashing |-beam never appears, despite all my best efforts (it's been weeks now). When I try to type something in the fields (neglecting the absence of the |-beam) the text appears in my current project file instead (where my cursor last was before running the project). I added other classes who use JTextField's, when I run their main method they work fine yet when I instantiate these classes somewhere in our project the frame does open but the textfields are yet again not selectable.
Here I provide the CubeAdderPanel class, I have trimmed it down a bit.
Updated according to replies
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import sourcecode.visualization.objects.Cube;
import java.util.HashMap;
import java.util.Map;
public class CubeAdderPanel extends JFrame {
private JTextField textFieldX;
private JTextField textFieldY;
private JTextField textFieldZ;
private JTextField textFieldSize;
private SolidButton addButton;
private SolidButton backButton;
private JLabel lblX;
private JLabel lblY;
private JLabel lblZ;
private JLabel lblSize;
private Font font = new Font("Open Sans Light", Font.PLAIN, 13);
private Map<JTextField, Double> textInput = new HashMap<>();
private final MenuHandler handler;
public CubeAdderPanel(MenuHandler handler){
this.handler = handler;
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setAlwaysOnTop(true);
setType(Type.UTILITY);
setResizable(false);
setUndecorated(true);
setBounds(1370, 130, 280, 210);
String osName = System.getProperty("os.name");
if (osName.contains("Mac")) {
setBounds(1130, 40, 280, 240);
}
initTextFields();
initButtons();
initLabels();
//initFocusTraversal();
initTextInputMap();
initTextActions();
//Creates JFrame layout
JSeparator separator = new JSeparator();
GroupLayout gl_panel = new GroupLayout(getContentPane());
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup()
.addGap(47)
.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING)
.addGroup(gl_panel.createSequentialGroup()
.addComponent(addButton, GroupLayout.PREFERRED_SIZE, 76, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, 31, Short.MAX_VALUE)
.addComponent(backButton, GroupLayout.PREFERRED_SIZE, 76, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panel.createSequentialGroup()
.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
.addComponent(lblX)
.addComponent(lblY, GroupLayout.PREFERRED_SIZE, 8, GroupLayout.PREFERRED_SIZE)
.addComponent(lblZ)
.addComponent(lblSize))
.addPreferredGap(ComponentPlacement.RELATED, 26, Short.MAX_VALUE)
.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
.addComponent(textFieldSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textFieldX, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textFieldY, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textFieldZ, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))))
.addGap(42))
.addGroup(gl_panel.createSequentialGroup()
.addComponent(separator, GroupLayout.PREFERRED_SIZE, 279, GroupLayout.PREFERRED_SIZE)
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(35)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(lblX)
.addComponent(textFieldX, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(textFieldY, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblY))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(textFieldZ, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblZ))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(lblSize)
.addComponent(textFieldSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addComponent(separator, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addGap(15)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(backButton, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)
.addComponent(addButton, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE))
.addContainerGap(46, Short.MAX_VALUE))
);
getContentPane().setLayout(gl_panel);
}
private void initTextInputMap() {
double empty = Double.POSITIVE_INFINITY;
textInput.put(textFieldX, empty);
textInput.put(textFieldY, empty);
textInput.put(textFieldZ, empty);
textInput.put(textFieldSize, empty);
}
private void saveTextInput(JTextField textField) {
try {
textInput.put(textField, Double.parseDouble(textField.getText()));
getFocusOwner().transferFocus();
} catch (NumberFormatException e) {
Toolkit.getDefaultToolkit().beep();
textField.setText("");
textInput.put(textField, Double.POSITIVE_INFINITY);
} finally {
boolean validInputs = hasValidInputs();
if (! hasValidInput(textField)) {
Toolkit.getDefaultToolkit().beep();
}
addButton.setEnabled(validInputs);
}
}
private void saveTextInputs() {
for (JTextField textField : textInput.keySet()) {
saveTextInput(textField);
}
}
private void initTextActions() {
for (JTextField textField : textInput.keySet()) {
textField.addActionListener((ActionEvent a) -> {
saveTextInput(textField);
});
}
}
private void initFocusTraversal() {
getContentPane().setFocusTraversalPolicy(
new SimpleFocusTraversalPolicy(
textFieldX, textFieldY, textFieldZ,
textFieldSize));
}
private void initTextFields() {
textFieldX = new JTextField();
textFieldX.setColumns(10);
textFieldX.setName("X");
textFieldY = new JTextField();
textFieldY.setColumns(10);
textFieldY.setName("Y");
textFieldZ = new JTextField();
textFieldZ.setColumns(10);
textFieldZ.setName("Z");
textFieldSize = new JTextField();
textFieldSize.setColumns(10);
textFieldSize.setName("Size");
}
private void initButtons() {
addButton = new SolidButton("add");
addButton.addActionListener((ActionEvent a) -> {
saveTextInputs();
if (!hasValidInputs()) {
Toolkit.getDefaultToolkit().beep();
cleanInvalidInputs();
} else {
float x = textInput.get(textFieldX).floatValue();
float y = textInput.get(textFieldY).floatValue();
float z = textInput.get(textFieldZ).floatValue();
float size = textInput.get(textFieldSize).floatValue();
Cube cube = new Cube(x, y, z, size, 360, 1);
handler.addCube(cube);
resetInputs();
}
});
addButton.setFont(font);
backButton = new SolidButton("back");
backButton.addActionListener((ActionEvent a) -> {
setVisible(false);
handler.restoreMenu();
});
backButton.setFont(font);
}
private void initLabels() {...}
private int counter = 1;
#Override
public void setVisible(boolean state) {
super.setVisible(state);
addButton.setEnabled(!state);
if (state) {
if (counter == 1) {
counter = 0;
super.setVisible(true);
}
textFieldX.requestFocus();
}
}
public void terminate() {
dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
}
private boolean hasValidInputs() {...}
private void cleanInvalidInputs() {...}
private boolean hasValidInput(JTextField textField) {...}
public void resetInputs() {...}
Thank you!! If any additional information is required I'll be happy to provide!
EDIT:
This simple TextField class provides a perfectly editable/focusable JTextField when I run JTextField.main().
package sourcecode.visualization.GUI;
import javax.swing.*;
public class TextField {
JFrame frame = new JFrame("Jtextfield demo");
JTextField textField = new JTextField("Hello from JTextField", 10);
public TextField() {
frame.add(textField);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TextField();
}
});
}
Yet when I call the TextField from anywhere inside our project it never is editable/focusable when I run Main.main(), despite trying all focus related functions etc, e.g. here I added a TextField object to our Pilot class.
....
import sourcecode.visualization.GUI.TextField;
public class Pilot implements ILogic {
TextField textField = new TextField();
....}
So this makes me believe the problem originates from an other class, not the CubeAdderPanel class, interfering with the JTextFields/swing, yet I don't know which one could cause this problem, we have looked in all of them, because all our code seems correct as it runs fine on Windows and Linux. Could it be the Shader, Mesh, Window, Renderer... class? What can cause this problem?
I can provide all of my code if that would aid in the problem, but I believe since this only affects one class really, it can be solved here, to simplify the issue.
I have a solitaire project (mind the package/class name, it was trial and error and I didn't delete the old projects) that refuses to accept the GameArea class I have, which extends JPanel. The GameArea works fine in its own separate instance where the tester class runs with only the JPanel on the JFrame. That tester class uses setContentPane(newGame) to add it to the JFrame.
In the class below, neither getContentPane().add(newGame) nor setContentPane(newGame) successfully adds the game to the frame. This class sets up a main menu, with two buttons. The first one takes it into the Start New Game screen, and then the button which is supposed to start the game will either:
1) show only a green screen if getContentPane().add(newGame) is used
2) show a pressed Start New Game, and then freeze on the Start New Game screen if setContentPane(newGame) is used. This is frustrating because getContentPane().removeAll() is called before this...However, using the menu, I can return to the main menu and still run in that infinite loop of freeze and fix.
I suspect because I don't know enough about swing classes yet that I'm missing something. Any help is greatly appreciated, since I need to have this done in 2 days.
package guitestersolitairenew;
/**
*
* #author Josh
* #version 1.00 2015/3/28
*/
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import static javax.swing.Action.MNEMONIC_KEY;
import static javax.swing.Action.SHORT_DESCRIPTION;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.GroupLayout;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class GUITesterSolitaireNew extends JFrame
{
public GUITesterSolitaireNew()
{
initComponents();
setMainMenu();
}
private void initComponents()
{
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setBackground(new java.awt.Color(80, 135, 40));
setTitle("Klondike Solitaire");
getContentPane().setBackground(new java.awt.Color(85,130,40));
setSize(1200,700);
setLocationRelativeTo(null);
setResizable(false);
JMenuBar menubar = new JMenuBar();
menubar.add(new JMenu("File"));
class MainMenu extends AbstractAction
{
public MainMenu(String text, ImageIcon icon, String desc, Integer mnemonic)
{
super(text,icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e)
{
setMainMenu();
}
}
menubar.getMenu(0).add(new JMenuItem(new MainMenu("Main Menu", null, "Return to the main menu.", KeyEvent.VK_M)));
class NewGame extends AbstractAction
{
public NewGame(String text, ImageIcon icon, String desc, Integer mnemonic)
{
super(text,icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e)
{
newGame(e);
}
}
menubar.getMenu(0).add(new JMenuItem(new NewGame("New Game", null, "Start a new game.", KeyEvent.VK_N)));
class RestartGame extends AbstractAction
{
public RestartGame(String text, ImageIcon icon, String desc, Integer mnemonic)
{
super(text,icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e)
{
//Fix to restart game.
}
}
menubar.getMenu(0)
.add(new JMenuItem(new RestartGame("Restart Game", null, "Restart the current game.", KeyEvent.VK_R)));
class LoadGame extends AbstractAction
{
public LoadGame(String text, ImageIcon icon, String desc, Integer mnemonic)
{
super(text,icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e)
{
//Fix to load game.
}
}
menubar.getMenu(0).add(new JMenuItem(new LoadGame("Load Game", null, "Load a saved game.", KeyEvent.VK_L)));
class SaveGame extends AbstractAction
{
public SaveGame(String text, ImageIcon icon, String desc, Integer mnemonic)
{
super(text,icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e)
{
//Fix to save game
}
}
menubar.getMenu(0).add(new JMenuItem(new SaveGame("Save Game", null, "Create a save file.", KeyEvent.VK_S)));
class ExitAction extends AbstractAction
{
public ExitAction (String text, ImageIcon icon, String desc, Integer mnemonic)
{
super(text, icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
menubar.getMenu(0).add(new JMenuItem(new ExitAction("Exit", null, "Exit from the program.", KeyEvent.VK_E)));
menubar.add(new JMenu("Help"));
class Rules extends AbstractAction
{
public Rules (String text, ImageIcon icon, String desc, Integer mnemonic)
{
super(text, icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e)
{
JFrame rules = new JFrame("Klondike Solitaire Rules");
rules.setSize(400,430);
rules.setLocationRelativeTo(null);
rules.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
JTextArea jta = new JTextArea();
jta.setEditable(false);
Component add = rules.add(jta);
JScrollPane jsp = new JScrollPane();
jsp.setViewportView(jta);
rules.getContentPane().add(jsp, java.awt.BorderLayout.CENTER);
jta.setCaretPosition(jta.getText().length());
jta.append("Klondike Solitaire Rules:\n\n");
jta.setCaretPosition(jta.getText().length());
jta.append("The game starts with a standard 52 card deck.\n");
jta.setCaretPosition(jta.getText().length());
jta.append("The cards are first dealt into 7 'tableaus' where the cards\n");
jta.setCaretPosition(jta.getText().length());
jta.append("are all turned face down and one card laid onto each tableau.\n");
jta.setCaretPosition(jta.getText().length());
jta.append("The left one is turned up, and the process is repeated for the\n");
jta.setCaretPosition(jta.getText().length());
jta.append("2nd to 7th tableaus. The 2nd card in the 2nd tableau is turned up.\n");
jta.setCaretPosition(jta.getText().length());
jta.append("Each tableau receives as many cards as the column position. The\n");
jta.setCaretPosition(jta.getText().length());
jta.append("last card in each tableau will be face up. The deck is placed\n");
jta.setCaretPosition(jta.getText().length());
jta.append("off to the side.\n\n");
jta.setCaretPosition(jta.getText().length());
jta.append("The cards are drawn one at a time from deck. Valid moves are: \n");
jta.setCaretPosition(jta.getText().length());
jta.append("-Move card from deck to tableau\n");
jta.setCaretPosition(jta.getText().length());
jta.append("-Move card from deck to foundation <stacks by suit>\n");
jta.setCaretPosition(jta.getText().length());
jta.append("-Click deck again for another card.\n");
jta.setCaretPosition(jta.getText().length());
jta.append("The deck is cycled if cards are remaining. The cards, after\n");
jta.setCaretPosition(jta.getText().length());
jta.append("being face up, will sort in descent of value and opposing\n");
jta.setCaretPosition(jta.getText().length());
jta.append("face color: i.e. a black 6 can only go on top of a red 7.\n\n");
jta.setCaretPosition(jta.getText().length());
jta.append("The player wins by moving all cards from the deck and tableaus\n");
jta.setCaretPosition(jta.getText().length());
jta.append("to the 4 foundations. The foundations sort by suit in ascending\n");
jta.setCaretPosition(jta.getText().length());
jta.append("order of value, starting with the ace. All aces are low.");
rules.setResizable(false);
rules.setVisible(true);
}
}
menubar.getMenu(1)
.add(new JMenuItem(new Rules("Rules", null, "Show a popup aid for the rules of the game.", KeyEvent.VK_R)));
class Info extends AbstractAction
{
public Info (String text, ImageIcon icon, String desc, Integer mnemonic)
{
super(text, icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e)
{
JFrame info = new JFrame("Development Info");
info.setSize(450,225);
info.setLocationRelativeTo(null); //sends it to center of screen
info.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); //does not close application, but actually kills the window when closed
JTextArea jta = new JTextArea();
jta.setEditable(false); //The user can't type on the text box.
Component add = info.add(jta); //abstraction that adds the component jta to window info
JScrollPane jsp = new JScrollPane();
jsp.setViewportView(jta); //puts the text area in the scroll pane
info.getContentPane().add(jsp, java.awt.BorderLayout.CENTER); //centers the text area and scroll pane to be the main subject of the frame
jta.setCaretPosition(jta.getText().length()); //sets the cursor to the end of the text typed so far
//edited out
info.setResizable(false);
info.setVisible(true);
}
}
menubar.getMenu(1)
.add(new JMenuItem(new Info("Info", null, "Information about Klondike Solitaire.", KeyEvent.VK_I)));
setJMenuBar(menubar);
}
private void newGame(java.awt.event.ActionEvent evt)
{
getContentPane().removeAll();
getContentPane().repaint();
setBackground(new java.awt.Color(80, 135, 40));
JLabel jLabel1 = new JLabel();
JButton jButton1 = new JButton();
jLabel1.setBackground(new java.awt.Color(80, 135, 40));
jLabel1.setFont(new java.awt.Font("Kunstler Script", 1, 120)); // NOI18N
jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.setText("Klondike Solitaire");
jLabel1.setVerticalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.setMaximumSize(new java.awt.Dimension(800, 100));
jLabel1.setMinimumSize(new java.awt.Dimension(800, 100));
jLabel1.setPreferredSize(new java.awt.Dimension(800, 100));
jLabel1.setRequestFocusEnabled(true);
jButton1.setText("Start New Game");
jButton1.setFont(new java.awt.Font("Times New Roman", 1, 20));
jButton1.setMaximumSize(new java.awt.Dimension(200, 50));
jButton1.setMinimumSize(new java.awt.Dimension(200, 50));
jButton1.setPreferredSize(new java.awt.Dimension(200, 50));
jButton1.addActionListener(new java.awt.event.ActionListener()
{
#Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
startNewGame();
}
});
JLabel replay = new JLabel("Replay game from seed:");
replay.setBackground(new java.awt.Color(80,135,40));
replay.setFont(new java.awt.Font("Times New Roman", 1, 20));
replay.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
replay.setVerticalAlignment(javax.swing.SwingConstants.CENTER);
replay.setMaximumSize(new java.awt.Dimension(220, 50));
replay.setMinimumSize(new java.awt.Dimension(220, 50));
replay.setPreferredSize(new java.awt.Dimension(220, 50));
JTextField getSeed = new JTextField();
getSeed.setCaretPosition(getSeed.getText().length());
getSeed.setFont(new java.awt.Font("Times New Roman", 1, 18));
getSeed.setMaximumSize(new java.awt.Dimension(150, 24));
getSeed.setMinimumSize(new java.awt.Dimension(150, 24));
getSeed.setPreferredSize(new java.awt.Dimension(150, 24));
JButton startSeed = new JButton("Start Game");
startSeed.setFont(new java.awt.Font("Times New Roman", 1, 20));
startSeed.setMaximumSize(new java.awt.Dimension(130, 30));
startSeed.setMinimumSize(new java.awt.Dimension(130, 30));
startSeed.setPreferredSize(new java.awt.Dimension(130, 30));
startSeed.addActionListener(new java.awt.event.ActionListener()
{
#Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
startNewGame(Integer.parseInt(getSeed.getText()));
}
});
JButton back = new JButton("Back to Main Menu");
back.setFont(new java.awt.Font("Times New Roman", 1, 20));
back.setMaximumSize(new java.awt.Dimension(200, 50));
back.setMinimumSize(new java.awt.Dimension(200, 50));
back.setPreferredSize(new java.awt.Dimension(200, 50));
back.addActionListener(new java.awt.event.ActionListener()
{
#Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
setMainMenu();
}
});
GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(GroupLayout.Alignment.CENTER)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
.addGroup(layout.createSequentialGroup()
.addGap(200, 200, 200)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
.addComponent(back, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(replay, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(getSeed, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(startSeed, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(jButton1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(layout.createSequentialGroup()
.addGap(200, 200, 200)
.addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
.addContainerGap(90, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(150, 150, 150)
.addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(10, 10, 10)
.addComponent(jButton1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(35, 35, 35)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
.addComponent(replay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getSeed, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(startSeed, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(180, 180, 180)
.addComponent(back, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
);
}
private void startNewGame()
{
getContentPane().removeAll();
getContentPane().repaint();
newGame.newGame();
Container pane = getContentPane();
pane.add(newGame);
setContentPane(pane);
getContentPane().revalidate();
getContentPane().repaint();
}
public void startNewGame(int seed)
{
getContentPane().removeAll();
getContentPane().repaint();
newGame.newGame();
add(newGame);
}
private void setMainMenu()
{
getContentPane().removeAll();
getContentPane().repaint();
setBackground(new java.awt.Color(80, 135, 40));
JLabel jLabel1 = new javax.swing.JLabel();
JButton jButton1 = new javax.swing.JButton();
JButton jButton2 = new javax.swing.JButton();
jLabel1.setBackground(new java.awt.Color(80, 135, 40));
jLabel1.setFont(new java.awt.Font("Kunstler Script", 1, 120)); // NOI18N
jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.setText("Klondike Solitaire");
jLabel1.setVerticalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.setMaximumSize(new java.awt.Dimension(800, 100));
jLabel1.setMinimumSize(new java.awt.Dimension(800, 100));
jLabel1.setPreferredSize(new java.awt.Dimension(800, 100));
jLabel1.setRequestFocusEnabled(true);
jButton1.setText("New Game");
jButton1.setFont(new java.awt.Font("Times New Roman", 1, 20));
jButton1.setMaximumSize(new java.awt.Dimension(200, 50));
jButton1.setMinimumSize(new java.awt.Dimension(200, 50));
jButton1.setPreferredSize(new java.awt.Dimension(200, 50));
jButton1.addActionListener(new java.awt.event.ActionListener()
{
#Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
newGame(evt);
}
});
jButton2.setText("Load Game");
jButton2.setFont(new java.awt.Font("Times New Roman", 1, 20));
jButton2.setMaximumSize(new java.awt.Dimension(200, 50));
jButton2.setMinimumSize(new java.awt.Dimension(200, 50));
jButton2.setPreferredSize(new java.awt.Dimension(200, 50));
GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(GroupLayout.Alignment.CENTER)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
.addGroup(layout.createSequentialGroup()
.addGap(200, 200, 200)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
.addComponent(jButton2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(layout.createSequentialGroup()
.addGap(200, 200, 200)
.addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
.addContainerGap(90, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(150, 150, 150)
.addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(10, 10, 10)
.addComponent(jButton1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(5, 5, 5)
.addComponent(jButton2)
.addContainerGap(120, Short.MAX_VALUE))
);
}
/**
* #param args the command line arguments
*/
public static void main(String args[])
{
/* Set the Nimbus look and feel */
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try
{
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
{
System.out.println("Main.main(): 492");
if ("Nimbus".equals(info.getName()))
{
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex)
{
java.util.logging.Logger.getLogger(GUITesterSolitaireNew.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new GUITesterSolitaireNew().setVisible(true);
}
});
}
private javax.swing.JInternalFrame jInternalFrame1;
private GameArea newGame = new GameArea();
}
Don't use setContentPane to switch views, use a CardLayout, that's what it's designed for. See How to Use CardLayout for more details
Also, there's little point to doing this...
setContentPane(pane);
getContentPane().revalidate();
getContentPane().repaint();
In this instance, it's not the contentPane that needs to be revalidated, it's the contentPanes parent...
I'm trying to make a program that uses Swing for the GUI, but the form that opens up when I run the code below is blank. I'm still able to get information regarding the objects that aren't seen, however (tested with getting btnLogin.getText()). Am I missing something, or am I doing something wrong?
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class loginForm extends JFrame implements ActionListener{
public static void main(String[] args){
new loginForm();
}
public loginForm() {
System.out.println("Starting...");
pack();
initComponents();
System.out.println("Opened");
this.setVisible(true);
}
private void initComponents() {
loginForm = new JFrame();
lblUserID = new JLabel();
existingUserIDTextField = new JTextField();
lblPassword = new JLabel();
existingUserPasswordField = new JPasswordField();
btnLogin = new JButton();
btnLogin.addActionListener(this);
lblWelcome = new JLabel();
//======== loginForm ========
{
loginForm.setResizable(false);
loginForm.setTitle("Library Reservation System");
Container loginFormContentPane = loginForm.getContentPane();
//---- lblUserID ----
lblUserID.setText("User ID:");
lblUserID.setFont(new Font("Tahoma", Font.PLAIN, 16));
//---- lblPassword ----
lblPassword.setText("Password:");
lblPassword.setFont(new Font("Tahoma", Font.PLAIN, 16));
//---- btnLogin ----
btnLogin.setText("Login");
//---- lblWelcome ----
lblWelcome.setText("Welcome to our Library Reservation System");
lblWelcome.setFont(new Font("Tahoma", Font.PLAIN, 16));
GroupLayout loginFormContentPaneLayout = new GroupLayout(loginFormContentPane);
loginFormContentPane.setLayout(loginFormContentPaneLayout);
loginFormContentPaneLayout.setHorizontalGroup(
loginFormContentPaneLayout.createParallelGroup()
.addGroup(loginFormContentPaneLayout.createSequentialGroup()
.addGroup(loginFormContentPaneLayout.createParallelGroup()
.addGroup(loginFormContentPaneLayout.createSequentialGroup()
.addGap(199, 199, 199)
.addComponent(btnLogin, GroupLayout.PREFERRED_SIZE, 145, GroupLayout.PREFERRED_SIZE))
.addGroup(loginFormContentPaneLayout.createSequentialGroup()
.addGap(72, 72, 72)
.addGroup(loginFormContentPaneLayout.createParallelGroup()
.addComponent(lblUserID, GroupLayout.PREFERRED_SIZE, 70, GroupLayout.PREFERRED_SIZE)
.addComponent(lblPassword))
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
.addGroup(loginFormContentPaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
.addComponent(existingUserIDTextField, GroupLayout.DEFAULT_SIZE, 287, Short.MAX_VALUE)
.addComponent(existingUserPasswordField, GroupLayout.DEFAULT_SIZE, 287, Short.MAX_VALUE)))
.addGroup(GroupLayout.Alignment.TRAILING, loginFormContentPaneLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblWelcome, GroupLayout.PREFERRED_SIZE, 318, GroupLayout.PREFERRED_SIZE)))
.addContainerGap(118, Short.MAX_VALUE))
);
loginFormContentPaneLayout.setVerticalGroup(
loginFormContentPaneLayout.createParallelGroup()
.addGroup(loginFormContentPaneLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblWelcome, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
.addGap(11, 11, 11)
.addGroup(loginFormContentPaneLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(lblUserID)
.addComponent(existingUserIDTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addGroup(loginFormContentPaneLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(lblPassword)
.addComponent(existingUserPasswordField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addComponent(btnLogin)
.addContainerGap(12, Short.MAX_VALUE))
);
loginForm.pack();
loginForm.setLocationRelativeTo(loginForm.getOwner());
}
}
private JFrame loginForm;
private JLabel lblUserID;
private JTextField existingUserIDTextField;
private JLabel lblPassword;
private JPasswordField existingUserPasswordField;
private JButton btnLogin;
private JLabel lblWelcome;
}
The frame containing the controls is never displayed.
loginForm.setVisible(true);
Instead of having an outer redundant frame class you could do
public class LoginFormApp extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
LoginFormApp loginFormApp = new LoginFormApp();
loginFormApp.initComponents();
}
});
.....
}
where initComponents makes the loginForm visible as previously stated.
I am trying to make a set of two JTextfields (side by side) appear inside of a panel when a button is clicked. The problem is that something like Flowlayout will make my textfields move all over the place (they line up in a single row or column), and Gridlayout makes the textfields far too big. I have investigated Springlayout and Grouplayout, but these layouts don't seem to have a straightforward way to add a component at runtime (plus the code is really messy looking to me, as seen in the example below).
This is an example of what I am trying to achieve with the layout...run the code and pay attention to how the JTextfields react when you resize the window (the add set of fields button doesn't work, because I am unsure of how to add components to the panel with the Grouplayout in place):
GoodLayout.java
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.EmptyBorder;
public class GoodLayout extends JFrame {
private JPanel contentPane;
private JTextField textField;
private JTextField textField_1;
private JTextField textField_2;
private JTextField textField_3;
private JTextField textField_4;
private JTextField textField_5;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GoodLayout frame = new GoodLayout();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public GoodLayout() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 383, 328);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
JButton buttonAddFields = new JButton("+ Add Set of Fields +");
buttonAddFields.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Add a set of fields to the panel");
}
});
contentPane.add(buttonAddFields, BorderLayout.SOUTH);
JPanel panel = new JPanel();
contentPane.add(panel, BorderLayout.CENTER);
textField = new JTextField();
textField.setColumns(10);
textField_1 = new JTextField();
textField_1.setColumns(10);
textField_2 = new JTextField();
textField_2.setColumns(10);
textField_3 = new JTextField();
textField_3.setColumns(10);
textField_4 = new JTextField();
textField_4.setColumns(10);
textField_5 = new JTextField();
textField_5.setColumns(10);
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addContainerGap()
.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_1, GroupLayout.DEFAULT_SIZE, 518, Short.MAX_VALUE))
.addGroup(gl_panel.createSequentialGroup()
.addComponent(textField_2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_3, GroupLayout.DEFAULT_SIZE, 518, Short.MAX_VALUE))
.addGroup(gl_panel.createSequentialGroup()
.addComponent(textField_4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_5, GroupLayout.DEFAULT_SIZE, 518, Short.MAX_VALUE)))
.addContainerGap())
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addContainerGap()
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textField_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(textField_2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textField_3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(textField_4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textField_5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addContainerGap(287, Short.MAX_VALUE))
);
panel.setLayout(gl_panel);
}
}
The important bit in the code above is the actionPerformed method...I would really like to find a simple solution that looks good (GUI layout-wise) when the button is clicked and a pair of textfields appear. Maybe there is a better layout for this? I used the Eclipse plugin WindowBuilder to build the code above, and I have tried all of the different layout options that seemed reasonable to try.
Any ideas or tricks about how to better tackle this problem are appreciated
Thanks, Dan
Do not discard the GroupLayout manager -- it is a very capable layout manager
and is one of the few managers that does things properly.
However, it is not suited for dynamic layout constructions due to the
way the layout is built. We would have to completely redo our layout and
do ad hoc calculations.
For this, we can easily use MigLayout. MigLayout is a third-party layout
manager that also does things properly. It is easy to use and very powerful.
package com.zetcode;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class GoodLayout2 extends JFrame {
private JPanel pnl;
public GoodLayout2() {
initUI();
setTitle("MigLayout solution");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void initUI() {
JButton addBtn = new JButton("Add");
addBtn.addActionListener(new AddAction());
pnl = new JPanel(new MigLayout("ins dialog, wrap 2"));
pnl.add(addBtn, "span 2, center");
pnl.add(new JTextField(10));
pnl.add(new JTextField(10), "pushx, growx");
pnl.add(new JTextField(10));
pnl.add(new JTextField(10), "pushx, growx");
pnl.add(new JTextField(10));
pnl.add(new JTextField(10), "pushx, growx");
add(pnl);
pack();
}
private class AddAction extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
pnl.add(new JTextField(10));
pnl.add(new JTextField(10), "pushx, growx");
pnl.doLayout();
pnl.repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GoodLayout2 ex = new GoodLayout2();
ex.setVisible(true);
}
});
}
}
I have placed the button to the north part of the window, since the code
is then slightly less complicated.
Background: I have a JPanel (PanelCarga extends JPanel) that displays as many sub-JPanels (DatosArchivo extends JPanel) as files I wish to open (n DatosArchivo panels) in my program for diferent purposes. This DatosArchivos contains a "X" button that I wish it to closes this DatosArchivos panel and then informs to the corresponding PanelCarga that it have been closed so that can reorganize in his grid the remaining n-1 DatosArchivo panels.
Tha PanelCarga Class:
package gui;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.sql.SQLException;
import java.util.LinkedList;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import logica.Cargador;
public class PanelCarga extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextField textField;
private final JPanel panel = new JPanel();
/**
* Create the panel.
*/
public PanelCarga() {
JLabel lblArchivosA = new JLabel("Archivo (-s) a cargar");
textField = new JTextField();
textField.setEditable(false);
textField.setColumns(10);
final JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(panel);
panel.setLayout(new GridLayout(0, 2, 0, 0));
JButton btnAbrir = new JButton("Abrir");
btnAbrir.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JFileChooser escoger = new JFileChooser();
escoger.setMultiSelectionEnabled(true);
int resultado = escoger.showOpenDialog(null);
File[] archivos = null;
String nombres = "";
if (resultado == JFileChooser.APPROVE_OPTION) {
archivos = escoger.getSelectedFiles();
for (int i = 0; i<archivos.length;i++){
if (i==0){
nombres = nombres + archivos [i].getName() ;
}else{
nombres = nombres + "; " +archivos [i].getName() ;
}
DatosArchivo datos = null;
try {
datos = new DatosArchivo();
} catch (SQLException e) {
JDialog error = new JDialog ();
error.setTitle("error");
JLabel mensaje = new JLabel(e.getMessage());
error.getContentPane().add(mensaje);
error.validate();
}
datos.textField_Ruta.setText(archivos[i].toString());
JTextField texto = new JTextField ();
texto.setBounds(10, 10, 100, 100);
panel.add(datos);
}
textField.setText(nombres);
panel.validate();
scrollPane.validate();
}
}
});
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(scrollPane, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblArchivosA)
.addGap(18)
.addComponent(textField, GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnAbrir)))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(6)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblArchivosA)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(btnAbrir))
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 423, Short.MAX_VALUE)
.addContainerGap())
);
setLayout(groupLayout);
}
public LinkedList <Cargador> getCargadores (){
LinkedList <Cargador> cargadores = new LinkedList <Cargador> ();
for (int i = 0; i < panel.getComponentCount(); i++){
cargadores.add(((DatosArchivo) panel.getComponent(i)).getCargador());
}
return cargadores;
}
public JPanel getPanel (){
return this.panel;
}
}
And the DatosArchivo Class:
package gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.BevelBorder;
import logica.Cargador;
import logica.Conector;
public class DatosArchivo extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
public JTextField textField_Ruta;
private JTextField textField_Anio;
private JTextField textField_UbicacionNueva;
private String usuario = "rpatrizio";
private final JComboBox comboBox_Ubicacion ;
private JComboBox comboBox_Dia;
private JComboBox comboBox_mes;
/**
* Create the panel.
* #throws SQLException
*/
public DatosArchivo() throws SQLException {
setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
JPanel panel = new JPanel();
JLabel lblArchivo = new JLabel("Archivo:");
textField_Ruta = new JTextField();
textField_Ruta.setEditable(false);
textField_Ruta.setColumns(10);
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addContainerGap()
.addComponent(lblArchivo)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_Ruta, GroupLayout.DEFAULT_SIZE, 190, Short.MAX_VALUE)
.addContainerGap())
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(5)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(lblArchivo)
.addComponent(textField_Ruta, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
panel.setLayout(gl_panel);
JPanel panel_1 = new JPanel();
JLabel lblUbicación = new JLabel("Ubicaci\u00F3n");
textField_UbicacionNueva = new JTextField();
textField_UbicacionNueva.setEditable(false);
textField_UbicacionNueva.setColumns(10);
String [] ubicaciones = Conector.getUbicacion();
comboBox_Ubicacion = new JComboBox(ubicaciones);
comboBox_Ubicacion.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (comboBox_Ubicacion.getSelectedItem().toString().equals("Agregar Nueva")){
textField_UbicacionNueva.setEditable(true);
}else {
textField_UbicacionNueva.setEditable(false);
}
}
});
String [] dias = {"","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"};
String [] meses = {"","enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre"};
JPanel panel_2 = new JPanel();
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(panel, GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 296, Short.MAX_VALUE)
.addComponent(panel_2, GroupLayout.PREFERRED_SIZE, 296, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(8)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(panel_2, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addGap(16))
);
JLabel lblFecha = new JLabel("Fecha");
comboBox_Dia = new JComboBox(dias);
JLabel lblDe = new JLabel("de");
comboBox_mes = new JComboBox(meses);
JLabel lblDe_1 = new JLabel("de");
textField_Anio = new JTextField();
textField_Anio.setColumns(10);
JButton btnX = new JButton("X");
btnX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
}
});
GroupLayout gl_panel_2 = new GroupLayout(panel_2);
gl_panel_2.setHorizontalGroup(
gl_panel_2.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_2.createSequentialGroup()
.addContainerGap()
.addComponent(lblFecha)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(comboBox_Dia, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblDe)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(comboBox_mes, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblDe_1)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_Anio, GroupLayout.PREFERRED_SIZE, 38, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnX)
.addGap(49))
);
gl_panel_2.setVerticalGroup(
gl_panel_2.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_2.createSequentialGroup()
.addGap(5)
.addGroup(gl_panel_2.createParallelGroup(Alignment.BASELINE)
.addComponent(lblFecha)
.addComponent(comboBox_Dia, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblDe)
.addComponent(comboBox_mes, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblDe_1)
.addComponent(textField_Anio, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(btnX))
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
panel_2.setLayout(gl_panel_2);
JButton button = new JButton("+");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (textField_UbicacionNueva.getText().equals("") || !textField_UbicacionNueva.isEnabled() || !comboBox_Ubicacion.getSelectedItem().equals("Agregar Nueva")){
String message = "Ubicación nueva no disponible";
JOptionPane.showMessageDialog(new JFrame(), message, "Dialog", JOptionPane.ERROR_MESSAGE);
}else{
}
}
});
GroupLayout gl_panel_1 = new GroupLayout(panel_1);
gl_panel_1.setHorizontalGroup(
gl_panel_1.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_1.createSequentialGroup()
.addGap(6)
.addComponent(lblUbicación)
.addGap(5)
.addComponent(comboBox_Ubicacion, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(11)
.addComponent(textField_UbicacionNueva, GroupLayout.PREFERRED_SIZE, 91, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(button)
.addContainerGap())
);
gl_panel_1.setVerticalGroup(
gl_panel_1.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_1.createSequentialGroup()
.addGap(9)
.addComponent(lblUbicación))
.addGroup(gl_panel_1.createSequentialGroup()
.addGap(5)
.addGroup(gl_panel_1.createParallelGroup(Alignment.BASELINE)
.addComponent(comboBox_Ubicacion, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textField_UbicacionNueva, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(button)))
);
panel_1.setLayout(gl_panel_1);
setLayout(groupLayout);
}
public Cargador getCargador(){
return new Cargador (this.getRuta(),this.getUbicacion(),this.getFecha(),this.getUsuario());
}
public String getFecha (){
return this.getAnio()+"-"+this.getMes()+"-"+this.getDia().toString()+" 00:00:00.000";
}
public String getUsuario (){
return this.usuario;
}
public String getRuta (){
return this.textField_Ruta.getText();
}
public String getAnio(){
return this.textField_Anio.getText();
}
public String getMes(){
String mes = null;
if (this.comboBox_mes.getSelectedItem().toString().equals("enero")){
mes = "01";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("febrero")){
mes = "02";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("marzo")){
mes = "03";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("abril")){
mes = "04";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("mayo")){
mes = "05";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("junio")){
mes = "06";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("julio")){
mes = "07";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("agosto")){
mes = "08";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("septiembre")){
mes = "09";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("octubre")){
mes = "10";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("noviembre")){
mes = "11";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("diciembre")){
mes = "12";
}
return mes;
}
public String getDia(){
return this.comboBox_Dia.getSelectedItem().toString();
}
public String getUbicacion(){
if (this.comboBox_Ubicacion.getSelectedItem().toString().equals("Agregar Nueva")){
if (this.textField_UbicacionNueva.getText().equals("")){
return null;
}else {
return this.textField_UbicacionNueva.getText();
}
}else if (this.comboBox_Ubicacion.getSelectedItem().toString().equals("")){
return null;
}else {
return this.comboBox_Ubicacion.getSelectedItem().toString();
}
}
}
Thanks in advance
I'm not sure if there is any one best way to do this, but I see two possible ways:
One way is to allow outside classes to add an ActionListener to the btnX held in DatosArchivo by giving this class a public method for doing this. Something like:
public void addbtnXActionListener(ActionListener listener) {
btnX.addActionListener(listener);
}
Then the outside class can delete that JPanel from its display if it wishes. The advantage of doing it this way is that the DatosArchivo need know nothing about the gui that's holding it. When I did it this way, I also gave the DatosArchivo a public getBtnX() method to return the btnX JButton. This is so I can match the JButton obtained from the ActionListener's actionPerformed method's getSource method to be able to decide which DatosArchivo object to dispose.
For example:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Foo002 {
private static void createAndShowUI() {
JFrame frame = new JFrame("Foo002");
frame.getContentPane().add(new PanelCarga2());
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();
}
});
}
}
#SuppressWarnings("serial")
class PanelCarga2 extends JPanel {
private static final Dimension PREF_SIZE = new Dimension(600, 400);
private JPanel datosArchivoContainer = new JPanel();
private BtnXListener btnXListener = new BtnXListener();
public PanelCarga2() {
JButton btnAbrir = new JButton("Abrir");
btnAbrir.addActionListener(new ActionListener() {
int index = 1;
public void actionPerformed(ActionEvent e) {
DatosArchivo2 datosArchivo2 = new DatosArchivo2(index);
datosArchivo2.addbtnXActionListener(btnXListener);
datosArchivoContainer.add(datosArchivo2);
datosArchivoContainer.revalidate();
index++;
}
});
JPanel topPanel = new JPanel();
topPanel.add(btnAbrir);
datosArchivoContainer.setLayout(new BoxLayout(datosArchivoContainer, BoxLayout.LINE_AXIS));
JScrollPane scrollPane = new JScrollPane(datosArchivoContainer);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
setPreferredSize(PREF_SIZE);
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
}
private class BtnXListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
Component[] components = datosArchivoContainer.getComponents();
for (int i = components.length - 1; i >= 0; i--) {
if (components[i] instanceof DatosArchivo2) {
DatosArchivo2 datoArchivo = (DatosArchivo2) components[i];
if (source.equals(datoArchivo.getBtnX())) {
datosArchivoContainer.remove(components[i]);
}
}
}
datosArchivoContainer.revalidate();
datosArchivoContainer.repaint();
}
}
}
#SuppressWarnings("serial")
class DatosArchivo2 extends JPanel {
private JButton btnX = new JButton("X");
public DatosArchivo2(int index) {
setPreferredSize(new Dimension(200, 200));
setBorder(BorderFactory.createEtchedBorder());
add(btnX);
add(new JLabel("Index: " + index));
}
public void addbtnXActionListener(ActionListener listener) {
btnX.addActionListener(listener);
}
public JButton getBtnX() {
return btnX;
}
}
Another way to do this is to give DatosArchivo a reference to its containing class and then having the DatosArchivo object handle its own deletion. The disadvantage to this is I believe that there is some increased cohesion. For this to work, I passed a reference of the containing PanelCarga into the DatosArchivo's constructor, and then gave PanelCarga a public removeDatosArchivo that the DatosArchivo method will call, passing itself as a parameter:
public void removeDatosArchivo(DatosArchivo3 datosArchivo) {
datosArchivoContainer.remove(datosArchivo);
datosArchivoContainer.revalidate();
datosArchivoContainer.repaint();
}
This whole example program looks like:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Foo003 {
private static void createAndShowUI() {
JFrame frame = new JFrame("Foo002");
frame.getContentPane().add(new PanelCarga3());
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();
}
});
}
}
#SuppressWarnings("serial")
class PanelCarga3 extends JPanel {
private static final Dimension PREF_SIZE = new Dimension(600, 400);
private JPanel datosArchivoContainer = new JPanel();
public PanelCarga3() {
JButton btnAbrir = new JButton("Abrir");
btnAbrir.addActionListener(new ActionListener() {
int index = 1;
public void actionPerformed(ActionEvent e) {
DatosArchivo3 datosArchivo3 = new DatosArchivo3(index, PanelCarga3.this);
datosArchivoContainer.add(datosArchivo3);
datosArchivoContainer.revalidate();
index++;
}
});
JPanel topPanel = new JPanel();
topPanel.add(btnAbrir);
datosArchivoContainer.setLayout(new BoxLayout(datosArchivoContainer, BoxLayout.LINE_AXIS));
JScrollPane scrollPane = new JScrollPane(datosArchivoContainer);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
setPreferredSize(PREF_SIZE);
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
}
public void removeDatosArchivo(DatosArchivo3 datosArchivo) {
datosArchivoContainer.remove(datosArchivo);
datosArchivoContainer.revalidate();
datosArchivoContainer.repaint();
}
}
#SuppressWarnings("serial")
class DatosArchivo3 extends JPanel {
private PanelCarga3 panelCarga;
private JButton btnX = new JButton("X");
public DatosArchivo3(int index, PanelCarga3 panelCarga) {
this.panelCarga = panelCarga;
btnX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnXActionPerformed(e);
}
});
setPreferredSize(new Dimension(200, 200));
setBorder(BorderFactory.createEtchedBorder());
add(btnX);
add(new JLabel("Index: " + index));
}
private void btnXActionPerformed(ActionEvent e) {
panelCarga.removeDatosArchivo(this);
}
}