Results 1 to 10 of 10
- 08-30-2009, 02:53 PM #1
Member
- Join Date
- Aug 2009
- Posts
- 14
- Rep Power
- 0
Layout problem / add components from another class
In a class Window extends JFrame i have a public static JPanel southPanel with a FlowLayout.
If i add a JLabel label1 to the southPanel from the Window class, it will be positioned right in the middle of the Jpanel according to the FlowLayout.
But if i add a JLabel label2 from another class (Window.southPanel.add(label2)), then it will be positionned at the left side of my JPanel southPanel, not centered anymore.
Does someone know why and how to solve this problem?
- 08-30-2009, 09:15 PM #2
Senior Member
- Join Date
- Aug 2009
- Posts
- 2,388
- Rep Power
- 6
Use a different Layout.
- 08-30-2009, 10:35 PM #3
Member
- Join Date
- Aug 2009
- Posts
- 14
- Rep Power
- 0
I created an exemple so it is easier to understand my problem.
Java Code:// Main Class ---------------------------------------------------- package test; public class Main { public static void main(String[] args) { Fenetre fen = new Fenetre(); fen.show(); } } ----------------------------------------------------------------- // Fenetre Class ------------------------------------------------- package test; import javax.swing.JLabel; public class Fenetre extends javax.swing.JFrame { public Fenetre() { initComponents(); JLabel jLabel1 = new JLabel("Fenetre"); staticPanel.add(jLabel1); } @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { container = new javax.swing.JPanel(); staticPanel = new javax.swing.JPanel(); panneau0 = new javax.swing.JPanel(); goPanneau1 = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); getContentPane().setLayout(null); container.setPreferredSize(new java.awt.Dimension(600, 400)); container.setLayout(null); staticPanel.setBackground(new java.awt.Color(204, 204, 255)); container.add(staticPanel); staticPanel.setBounds(30, 180, 530, 130); panneau0.setBackground(new java.awt.Color(204, 255, 204)); panneau0.setLayout(null); goPanneau1.setText("Go Panneau 1"); goPanneau1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { goPanneau1ActionPerformed(evt); } }); panneau0.add(goPanneau1); goPanneau1.setBounds(210, 60, 99, 23); container.add(panneau0); panneau0.setBounds(0, 0, 600, 150); getContentPane().add(container); container.setBounds(0, 0, 600, 400); java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); setBounds((screenSize.width-600)/2, (screenSize.height-400)/2, 600, 400); }// </editor-fold> private void goPanneau1ActionPerformed(java.awt.event.ActionEvent evt) { Panneau1 currentPanel = new Panneau1(); Fenetre.container.add(currentPanel); Fenetre.container.remove(panneau0); currentPanel.setBounds(0,0,600,150); } // Variables declaration - do not modify public static javax.swing.JPanel container; private javax.swing.JButton goPanneau1; private javax.swing.JPanel panneau0; public static javax.swing.JPanel staticPanel; // End of variables declaration } ------------------------------------------------------------------ // Panneau1 Class package test; import javax.swing.JLabel; public class Panneau1 extends javax.swing.JPanel { public Panneau1() { initComponents(); JLabel jLabel2 = new javax.swing.JLabel(); jLabel2.setText("LALALA"); Fenetre.staticPanel.add(jLabel2); jLabel2.setSize(100,30); } @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { setBackground(new java.awt.Color(204, 255, 204)); setPreferredSize(new java.awt.Dimension(600, 150)); setLayout(null); }// </editor-fold> }
Can anyone explain why jLabel1 is centered in the staticPanel according to the defaut FlowLayout and not jLabel2?Last edited by Fubarable; 08-31-2009 at 01:55 PM. Reason: Code tags added for readability
-
To be able to help you best here, we have to know what you are trying to achieve. If you re-read your posts carefully, you'll see that no where do you tell us why the current situation is wrong nor do you tell us what the right configuration is. You can imagine that it will be very difficult for us to give you anything more than the most general advise (i.e., "use a different layout manager") without knowing more. The ball is back in your court.
-
Also,
1) when adding and removing components, don't forget to call revalidate and repaint:
2) I would advise you strongly not to use a null layout here.Java Code:private void goPanneau1ActionPerformed( java.awt.event.ActionEvent evt) { Panneau1 currentPanel = new Panneau1(); Fenetre.container.add(currentPanel); Fenetre.container.remove(panneau0); currentPanel.setBounds(0, 0, 600, 150); // Added *** Fenetre.container.revalidate(); Fenetre.container.repaint(); }
- 08-31-2009, 02:11 PM #6
Member
- Join Date
- Aug 2009
- Posts
- 14
- Rep Power
- 0
Thanks a lot Fubarable, you were right, my problem was because i did not use revalidate().. shame on me..
Why do you think it is not advised to use a null Layout please?
-
Many use null layout when we must, when no other options are available, but try to avoid it for most tasks as it makes the program layout quite rigid and non-adaptable to different OS's or to changes.
- 08-31-2009, 10:08 PM #8
Member
- Join Date
- Aug 2009
- Posts
- 14
- Rep Power
- 0
Ah ok.. so i'll be more careful cause i need to move from windows to debian later..
Thanls a lot.
-
I'm not sure if you're still following this question, but if so, I often find it is best to illustrate the problem and solution with an example:
Say you wanted to create a JPanel to go into a dialog window that holds a JLabel that asks a question located at the top, 3 JRadioButton choices in a column in the middle, and an OK JButton at the bottom. If so, you could easily create something with a null layout like so:
But try to resize this, and you'll find that it's very rigid. Even more frustrating, what if you want to make it so that it can display four answers instead of three? That would mean adding another JRadioButton, moving the button down and increasing the size of the JPanel. What if you wanted to add another button next to the first one? Then you'll have to resize the button, add another one, tweak here and there to make sure all fits right. And lord help you if you want to make it display a variable number of answer JRadioButtons, one that could vary with each Question...Java Code:public class QuestionPanelNullLayout extends JPanel { public QuestionPanelNullLayout() { setLayout(null); setPreferredSize(new Dimension(270, 174)); JLabel questionLabel = new JLabel("What color is Washington's white horse"); JRadioButton blackBtn = new JRadioButton("Black"); JRadioButton blueBtn = new JRadioButton("Blue"); JRadioButton whiteBtn = new JRadioButton("White"); JButton okBtn = new JButton("OK"); questionLabel.setBounds(10, 10, 249, 16); blackBtn.setBounds(10, 36, 249, 24); blueBtn.setBounds(10, 70, 249, 24); whiteBtn.setBounds(10, 104, 249, 24); okBtn.setBounds(10, 138, 249, 26); add(questionLabel); add(blackBtn); add(blueBtn); add(whiteBtn); add(okBtn); }
So you find that any alteration affects many of the components already there and requires more and more work.
Now what if on the other hand you created your app using layout managers?
We can make the main JPanel use a BorderLayout and then add the questionLabel to the top via BorderLayout.NORTH:
The radiobuttons we can add into a JPanel created to hold them that uses GridLayout with one column and variable number of rows: GridLayout(0, 1, 10, 10) (the 10, 10 is to place 10 point vertical and horizontal gaps between all added components):Java Code:JLabel questionLabel = new JLabel("What color is Washington's white horse"); setLayout(new BorderLayout(10, 10)); add(questionLabel, BorderLayout.NORTH);
and then we can add the possibleAnswerPanel to the main JPanel BorderLayout.CENTER:Java Code:String[] possibleAnswers = {"Black", "Blue", "White"}; JPanel possibleAnswerPanel = new JPanel(new GridLayout(0, 1, 10, 10)); for (int i = 0; i < possibleAnswers.length; i++) { JRadioButton radioButton = new JRadioButton(possibleAnswers[i]); possibleAnswerPanel.add(radioButton); }
Finally the button can be added to its own JPanel that uses a GridLayout with one row and variable number of columns: GridLayout(1, 0, 10, 10) (again the 10, 10 for vertical and horizontal gaps):Java Code:setLayout(new BorderLayout(10, 10)); add(questionLabel, BorderLayout.NORTH); add(possibleAnswerPanel, BorderLayout.CENTER);
And this buttonPanel can be added to the main panel (that uses BorderLayout) in the BorderLayout.SOUTH position:Java Code:JButton okBtn = new JButton("OK"); JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 10, 10)); buttonPanel.add(okBtn);
So the new panel in fact looks exactly like the first, except now if I add a new answer by extending the string array:Java Code:setLayout(new BorderLayout(10, 10)); add(questionLabel, BorderLayout.NORTH); add(possibleAnswerPanel, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH);
the app will automatically resize to fit the new answer. Likewise, if I add another button,Java Code:String[] possibleAnswers = {"Black", "Blue", "White", "Red"};
the GUI will automatically move things to accommodate it.Java Code:JButton okBtn = new JButton("OK"); JButton cancelBtn = new JButton("Cancel"); JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 10, 10)); buttonPanel.add(okBtn); buttonPanel.add(cancelBtn);
A working class might look something like this:
QuestionPanelWithLayout.java
and could be displayed and used like so:Java Code:import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class QuestionPanelWithLayout extends JPanel{ private static final String OK = "OK"; private static final String CANCEL = "Cancel"; private String[] possibleAnswers; private int answerIndex; private ButtonGroup btnGrp = new ButtonGroup(); private boolean okSelected = false; private boolean answerCorrect = false; private String selectedAnswer = ""; public QuestionPanelWithLayout(String questionString, String[] possibleAnswers, int index) { this.possibleAnswers = possibleAnswers; this.answerIndex = index; JPanel questionPanel = new JPanel(new GridLayout(0, 1, 10, 10)); for (String answer : possibleAnswers) { JRadioButton radioBtn = new JRadioButton(answer); radioBtn.setActionCommand(answer); btnGrp.add(radioBtn); questionPanel.add(radioBtn); } JButton okBtn = new JButton(OK); JButton cancelBtn = new JButton(CANCEL); BtnListener btnListener = new BtnListener(); okBtn.addActionListener(btnListener); cancelBtn.addActionListener(btnListener); JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 10, 10)); buttonPanel.add(okBtn); buttonPanel.add(cancelBtn); setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); setLayout(new BorderLayout(10, 10)); add(new JLabel(questionString, SwingConstants.LEFT), BorderLayout.NORTH); add(questionPanel, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); } public boolean isAnswerCorrect() { return answerCorrect; } public boolean isOkSelected() { return okSelected; } public String getSelectedAnswer() { return selectedAnswer; } private class BtnListener implements ActionListener { public void actionPerformed(ActionEvent e) { String actionCommand = e.getActionCommand(); if (actionCommand.equals(OK)) { okSelected = true; ButtonModel bModel = btnGrp.getSelection(); if (bModel != null) { selectedAnswer = bModel.getActionCommand(); if(possibleAnswers[answerIndex].equals(selectedAnswer)) { answerCorrect = true; } else { answerCorrect = false; } } } else { okSelected = false; answerCorrect = false; } Window win = SwingUtilities.getWindowAncestor(QuestionPanelWithLayout.this); win.dispose(); } } }
ShowQuestion.java
Java Code:import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ShowQuestion { private static String questionString = "What color was Washington's white horse?"; private static String[] answers = { "Black", "Blue", "White" //, "Red" }; private static final JFrame frame = new JFrame("Ask Question"); private static void createAndShowGUI() { JButton showQuestionBtn = new JButton("Show Question"); showQuestionBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { showQuestionActionPerformed(); } }); JPanel panel = new JPanel(); panel.setPreferredSize(new Dimension(200, 100)); panel.add(showQuestionBtn); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(panel); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } private static void showQuestionActionPerformed() { QuestionPanelWithLayout questionPanel = new QuestionPanelWithLayout(questionString, answers, 2); JDialog dialog = new JDialog(frame, "Question", true); dialog.getContentPane().add(questionPanel); dialog.pack(); dialog.setLocationRelativeTo(null); dialog.setVisible(true); if (questionPanel.isOkSelected()) { System.out.println("Selected Answer: \"" + questionPanel.getSelectedAnswer() + "\"; Correct?: " + questionPanel.isAnswerCorrect()); } else { System.out.println("Question Canceled"); } } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } }
- 09-02-2009, 10:42 AM #10
Member
- Join Date
- Aug 2009
- Posts
- 14
- Rep Power
- 0
Similar Threads
-
[SOLVED] Layout Problem
By casid in forum New To JavaReplies: 4Last Post: 06-02-2009, 11:17 PM -
JFrame 's components size and location problem
By petrosgraf in forum Threads and SynchronizationReplies: 5Last Post: 04-18-2009, 02:24 AM -
Inconsistent layout w/dynamic resize of components
By donb2000 in forum AWT / SwingReplies: 3Last Post: 07-26-2008, 02:40 PM -
Problem In Swing Components
By SANDY_INDIA in forum AWT / SwingReplies: 1Last Post: 07-19-2008, 10:23 PM -
How to use LineMetrics class to layout characters along a line
By Java Tip in forum java.awtReplies: 0Last Post: 06-25-2008, 10:35 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks