What improvements should be made to this JDialog snippet? - java

I wrote a small function that will display a table inside a dialog and am looking for advice on what to clean up and what is better programming practice when it comes to dealing with swing.
What improvements can be made to my code
//constraints for panel to fill out the frame
GridBagConstraints grid = new java.awt.GridBagConstraints();
grid.fill = java.awt.GridBagConstraints.BOTH;
grid.weightx = 1.0;
grid.weighty = 1.0;
//create jtable based on a table model created from an array
JTable table = new JTable(testModel); //a method creates my test model
table.add(table.getTableHeader(), BorderLayout.PAGE_START);
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(testModel);
table.setRowSorter(sorter);
//add scrollpane for visibility
JScrollPane jscrollpane = new JScrollPane(table);
table.setFillsViewportHeight(true);
//add the scrollpane to a panel
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.add(jscrollpane, grid);
//create for use with the dialog
JFrame frame = new JFrame();
JDialog dialog = new JDialog(frame, "My Test Dialog", true);
dialog.add(panel);
dialog.pack();
dialog.setLocationRelativeTo(null); //added as advice of Stripies
dialog.setVisible(true);
I'm open to all constructive criticism as my goal is to learn the proper techniques for programming with swing.
To clarify, I'm looking whether I can take anything out or improve any of it.

What are the benefits of using setLocationByPlatform(true)?
Using setLocationRelativeTo(null) is a convenient choice for examples, demos and utilities. Quality applications preserve the user's preferred position, possibly recording the most recent setting in an instance of java.util.Preferences. Because a user's experience varies by platform, setLocationByPlatform(true) represents the implementer's best effort to meet that expectation. It's a better choice for the default location when no preference yet exists.

Related

Java: What Layout Manager would be best for a game menu?

===================
Game Name
Play
Exit
===================
the above is what my previous game menu looked like. I used the Box Layout to create it but it was very tedious. Is there there a better layout manager that I could use?
here is the code for those that asked of the main pane.
private JButton JB;
private JButton EB;
private JOptionPane JO;
public StartUpWindow(){
super("Pong");
JPanel outside = new JPanel();
JPanel inside = new JPanel();
setLayout(new BorderLayout());
outside.setLayout(new BoxLayout(outside, BoxLayout.LINE_AXIS));
inside.setLayout(new BoxLayout(inside, BoxLayout.PAGE_AXIS));
outside.add(Box.createHorizontalStrut(280));
outside.add(inside);
outside.add(Box.createHorizontalStrut(20));
inside.add(Box.createVerticalStrut(20));
JLabel title = new JLabel(" "+"Pong");
title.setFont( new Font("Serif", Font.BOLD, 40));
inside.add(title);
inside.add(Box.createVerticalStrut(20));
JButton btt1 = new JButton("Start");
Dimension d = new Dimension(200,40);
btt1.setSize(d);
btt1.setMinimumSize(d);
btt1.setMaximumSize(d);
btt1.setPreferredSize(d);
JButton btt2 = new JButton("Credits");
btt2.setSize(d);
btt2.setMinimumSize(d);
btt2.setMaximumSize(d);
btt2.setPreferredSize(d);
JButton btt3 = new JButton("Exit");
btt3.setSize(d);
btt3.setMinimumSize(d);
btt3.setMaximumSize(d);
btt3.setPreferredSize(d);
inside.add(btt1);
btt1.addActionListener(this);
btt1.setActionCommand("start");
inside.add(Box.createVerticalStrut(5));
inside.add(btt2);
btt2.addActionListener(this);
btt2.setActionCommand("credits");
inside.add(Box.createVerticalStrut(5));
inside.add(btt3);
btt3.addActionListener(this);
btt3.setActionCommand("exit");
inside.add(Box.createVerticalStrut(20));
add(outside);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
this.setResizable(false);
this.setLocation(450,200);
inside.setBackground(Color.GRAY);
outside.setBackground(Color.GRAY);
}
I agree that BoxLayout is tedious but I admire its relative simplicity.
Another quick and easy option is to use the "javax.swing.Box" class instead of using a layout manager directly.
Box box = Box.createVerticalBox();
box.add(new JLabel("Game"));
box.add(Box.createVerticalStrut(20));
box.add(new JLabel("Button 1"));
box.add(new JLabel("Button 2"));
JFrame frame = new JFrame();
frame.add(box);
frame.pack();
frame.setVisible(true);
Box offers a number of useful methods. You can use it to create vertical and horizontal boxes, create "struts" to reserve horizontal and vertical space, and create "glue" to fill in available space when the layout grows.
Of course you could also use GridBagLayout, but I tend to reserve it for more complex layouts. Box and his cousin BoxLayout are often good enough for simple layouts and are easy for new programmers who are maintaining the application to understand and debug.
Why not simply use no layout and instead draw everything using a Graphics object?
You could easily achieve this by creating a BufferStrategy bound to the Window object (invoke createBufferStrategy on the latter) then call a few simple methods to easily redraw the screen.
This also means it's simpler to then code the game's display when you're playing it.
BufferStrategy also allows the use of page flipping and other forms of buffering when the application is in fullscreen exclusive mode, allowing it to refresh the screen very rapidly in many applications.

Adding JScrollPane to JTable doesn't show up

I'm pretty new to Javas swings, so sorry if this is something trivial. This is the constructor, I excluded unnecessary form items. (I tried running the code as short as this, but the problem still appears)
//This just opens a connection to MySQL server, this doesn't create any problems.
bp = BazaPodataka.getBaza();
//Forming the main frame..
JFrame frame = new JFrame();
{
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setBounds(d.width/2 - sirina/2, d.height/2 - visina/2, sirina, visina);
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout(0, 0));
//Adding a layered pane so I can place items inside the form more 'freely'
JLayeredPane layeredPane = new JLayeredPane();
frame.getContentPane().add(layeredPane, BorderLayout.CENTER);
//Adding a table
JTable table = new JTable();
String[] rowData = {"Name:", "Price:", "Cathegory:", "Sum:"};
DefaultTableModel model = new DefaultTableModel(rowData, 0);
JScrollPane skrol = new JScrollPane(table);
table.setModel(model);
//The 2 lines below work as intended
ResultSet rs = (ResultSet) bp.query("SELECT * FROM table"); //This calls a query
popuniTabelu(rs, model); //This populates the table.
table.setBounds(10, 110, 500, 350);
table.setEnabled(false);
table.setShowHorizontalLines(false);
layeredPane.add(table);
Populating the table and displaying it isn't the problem, there's enough information inside the table 'table' that the user even needs to scroll down.
But that's where the problem begins, the scroll doesn't show up. How do I implement it from here. I tried following solutions I found on google, but they pretty much sum up on:
JScrollPane scroll = new JScrollPane(table);
Which simply doesn't work in my case.
The problem may be trivial, if it is, I'm sorry, I'm still learning swing. Also, sorry for my bad english, it's not my native language. :)
Also, if there's something I forgot to include, please let me know.
Thank you!
You add your table to 2 components :
JScrollPane skrol = new JScrollPane(table);
and
layeredPane.add(table);
Because of Swing component can have just one parent component second statment override first, so your JScrollPane is empty. Seems you need to remove layeredPane.add(table);
As mentioned here
Each GUI component can be contained only once. If a component is already in a container and you try to add it to another container, the component will be removed from the first container and then added to the second.

Buttons overwriting each other

So my buttons are overwriting each other, instead of all going up North like a tool bar..
I'm trying to get the buttons to go up North if that makes sense. I know my GUI is awful, and I'll rewire it once I get this prototype done.
// panels
mainPuzzlerPanel = new Panel();
mainPuzzlerPanel.setLayout(new BorderLayout());
puzzlePanel = new Panel();
//mainPuzzlerPanel.setLayout(null);
puzzlePanel.setLocation(100, 120);
// text fields
debugTxt = new TextArea(null,6,40,1);
debugTxt.setEditable(false);
mainPuzzlerPanel.add(debugTxt,BorderLayout.NORTH);
// buttons
Button newPuzzle = new Button("New Puzzle");
Button loadImage = new Button("Load Image");
Button assignLocation = new Button("Assign Location");
Button assignTimestamp = new Button("Assign Timestamp");
Button savePuzzle = new Button("Save Puzzle");
Button clearPuzzleCreator = new Button("Clear");
newPuzzle.addActionListener(this);
loadImage.addActionListener(this);
assignLocation.addActionListener(this);
assignTimestamp.addActionListener(this);
savePuzzle.addActionListener(this);
clearPuzzleCreator.addActionListener(this);
mainPuzzlerPanel.add(assignLocation,BorderLayout.NORTH);
mainPuzzlerPanel.add(assignTimestamp,BorderLayout.NORTH);
mainPuzzlerPanel.add(loadImage,BorderLayout.NORTH);
mainPuzzlerPanel.add(savePuzzle,BorderLayout.NORTH);
mainPuzzlerPanel.add(clearPuzzleCreator,BorderLayout.NORTH);
mainPuzzlerPanel.add(newPuzzle,BorderLayout.NORTH);
mainPuzzlerPanel.add(puzzlePanel,BorderLayout.CENTER);
add(mainPuzzlerPanel, "Controls");
setSize(1200, 700);
setVisible(true);
You can't add all the components BorderLayout.NORTH, makes no sense. Instead, add the JButtons to a JPanel that uses a different layout, say GridLayout, and then add that JPanel BorderLayout.NORTH. But most important -- read a tutorial on how to use the layout managers. It looks like you're guessing at this and that's not an efficient way to learn how to use these complex tools.
Regading,
I know my GUI is awful, and I'll rewire it once I get this prototype done.
Also not a good plan. It's much easier to write it well the first time through.
e.g.,
// after creating all of your JButtons, put them in an array...
JButton[] btnArray = {newPuzzle, loadImage, assignLocation, assignTimestamp,
savePuzzle, clearPuzzleCreator};
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
for (JButton btn : btnArray) {
buttonPanel.add(btn);
}
mainPuzzlerPanel.add(buttonPanel, BorderLayout.NORTH);
Edit: Oops, I notice now you're using Buttons and Panels, not JButtons and JPanels. I urge you to change your app to be a Swing app not an AWT app.
Layout manager tutorial: Laying Out Components Within a Container

createVerticalGlue() in BoxLayout not functioning

I have used the createVerticalGlue() successfully on a number of times. However in the following screen building code it is not working. I am still wondering why.
The situation is that I have two JPanels (leftPanel, rightPanel) within another Panel (centralPanel). Each of these two panels will host two JComponents using a BoxLayout Y-Axis. I want to distribute the remaining free space before, between and after the two JComponents.
I know that I can use empty borders and rigid areas to solve the problem but it happens that I am a bit hard headed!
My appologies for the long question.
public class MemberGUI extends JFrame {
JPanel contPane = (JPanel) this.getContentPane();
JPanel centralPanel = new JPanel();
JPanel leftPanel = new JPanel();
JPanel rightPanel = new JPanel();
JPanel lowerPanel = new JPanel();
JLabel title = new JLabel("Add/Delete Member");
JLabel nameLbl = new JLabel("Member's name");
JLabel idLbl = new JLabel ("Member ID");
JTextField nameFld = new JTextField(10);
JTextField idFld = new JTextField(10);
public void buildMe(){
//LayoutManagers
contPane.add(title,BorderLayout.PAGE_START);
contPane.add(centralPanel,BorderLayout.CENTER);
contPane.add(lowerPanel,BorderLayout.PAGE_END);
centralPanel.add(leftPanel);
centralPanel.add(rightPanel);
leftPanel.setLayout(new BoxLayout(leftPanel,BoxLayout.Y_AXIS));
rightPanel.setLayout(new BoxLayout(rightPanel,BoxLayout.Y_AXIS));
//leftPanel.add(Box.createRigidArea(new Dimension(0,50)));
leftPanel.add(Box.createVerticalGlue());
leftPanel.add(idLbl);
leftPanel.add(Box.createVerticalGlue());
leftPanel.add(nameLbl);
leftPanel.add(Box.createVerticalGlue());
//rightPanel.add(Box.createRigidArea(new Dimension(0,50)));
rightPanel.add(Box.createVerticalGlue());
rightPanel.add(idFld);
rightPanel.add(Box.createVerticalGlue());
rightPanel.add(nameFld);
rightPanel.add(Box.createVerticalGlue());
// JFrame Settings
this.setSize(500,400);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}
afaics, centralPanel has default layoutManager, which is FlowLayout. This always sizes its children to their prefSize, so the glue never comes into play.
Nesting containers comes at a price (which nesting wizards like #Andrew happily pay :-) Also, it's not entirely trivial to get right (f.i. replace the upper textField with a comboBox to see the mis-alignment). In the longer run, there's hardly a route around learning to master a more powerful manager, like f.i. MigLayout (my current personal favorite)

Java Positioning a list on a GUI

I'm trying to add a JList to a GUI, but am wondering how to position it? I want it to appear on the right hand side of the TextArea for data that will be sent to the GUI for selection.
Can anyone suggest how to do this? Here is the code (note: very new to Java and GUI's)
protected static void createAndShowGUI() {
GUI predict = new GUI();
JFrame frame = new JFrame("Phone V1.0");
frame.setContentPane(predict.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setMinimumSize(new Dimension(300, 400));
frame.setVisible(true); // Otherwise invisible window
}
private JPanel createContentPane() {
JPanel pane = new JPanel();
TextArea = new JTextArea(5, 10);
TextArea.setEditable(false);
TextArea.setLineWrap(true);
TextArea.setWrapStyleWord(true);
TextArea.setWrapStyleWord(true);
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
//Adds the buttons from Top to Bottom
String[] items = {"dsfsdfd"};
list = new JList(items);
JScrollPane scrollingList = new JScrollPane(list);
int orient = list.getLayoutOrientation();
JPanel window = new JPanel();
pane.add(window);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(5, 3));
JButton[] buttons = new JButton[] {
new JButton("Yes"),
new JButton(""),
new JButton("Clr"),
new JButton("1"),
new JButton("2abc"),
new JButton("3def"),
new JButton("4ghi"),
new JButton("5jkl"),
new JButton("6mno"),
new JButton("7pqrs"),
new JButton("8tuv"),
new JButton("9wxyz"),
new JButton("*+"),
new JButton("0_"),
new JButton("^#")
}; // Array Initialiser
for (int i = 0; i < buttons.length; i++) {
buttonPanel.add(buttons[i]);
buttons[i].addActionListener(this);
}
pane.add(TextArea);
pane.add(list);
pane.add(buttonPanel);
return pane;
}
Read the section from the Swing tutorial on Using Layout Mananger. There is no need to only use a single layout manager. You can nest layout managers to get the desired effect.
Wrap your TextArea and list in a new panel with a BorderLayout manager. Basically the BorderLayout manager lets you arrange components using north, south, east, west and center coordinates. The components at the center takes all available space as the parent container has more space available to it.
private JPanel createContentPane() {
JPanel pane = new JPanel(); //this is your main panel
JPanel textAreaPanel = new JPanel(new BorderLayout()); //the wrapper
//Some more code...
//Then at the end
//Make your TextArea take the center
textAreaPanel.add(TextArea, BorderLayout.CENTER);
//And the list to the east
textAreaPanel.add(list, BorderLayout.EAST);
pane.add(textAreaPanel);
pane.add(buttonPanel);
return pane;
}
The cool thing is that you can nest panels inside other panels, adding them different layout managers to get your desired layout.
On an unrelated note, try to follow Java naming conventions. Instead of JTextArea TextArea use JTextArea textArea. It makes it easier for you and people reading your code to understand it.
You could use a layout manager like Mig Layout for that kind of positionning.
(source: miglayout.com)
I could recommend you FormLayout. Before I found this layout I had a real pain with GridBagLayout. FormLayout is more powerful and much more convenient to learn and use and it is free. Give it a chance.
As others suggested, familiarize yourself with the concept of layout managers. There are several that come with the standard Swing API and several good 3rd party ones out there.
In addition, you will want to add the JList to a scroll pane (JScrollPane). You may want to consider adding it to a split pane (JSplitPane). And by consider I don't mean "do it because some guy on the net said so" I mean "do it if it makes sense for your end users".

Categories

Resources