I have a task of implementing MPJ-Express in Java Swing, unfortunately It isn't going well. I keep getting multiple JFrames when I execute the code. I have used OOP concepts. For now I'm just using a simple JFrame to show a Button and when I click the button it should give me the Rank and the Size of the Processes.
I have tried everything but all in vane going from sequential programming to OOP. I did try one thing is when the rank is 0 It shows 1 JFrame but when I click the button I get only the rank 0 every time, I want all the ranks shown.
public class Main {
public static void main(String[] args) {
Gui gui = new Gui(args);
}
}
public class Process extends mpi.MPI {
public final int rank;
public final int size;
public Process(String[] args){
super.Init(args);
this.rank = COMM_WORLD.Rank();
this.size = COMM_WORLD.Size();
}
public void exec() {
System.out.println("Rank <" + rank + ">");
System.out.println("Size <" + size + ">");
}
public void processFinalize() throws Throwable {
super.finalize();
}
}
class Gui {
Process p;
public Gui(String[] args) {
p = new Process(args);
welcomeScreen();
}
private void welcomeScreen() {
// Create and set up a frame window
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("MPJ Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set the panel to add buttons
JPanel panel = new JPanel();
BoxLayout boxlayout = new BoxLayout(panel, BoxLayout.X_AXIS);
panel.setLayout(boxlayout);
// Set border for the panel
panel.setBorder(new EmptyBorder(new Insets(150, 200, 150, 200)));
JButton jb1 = new JButton("Button 1");
jb1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Rank <" + p.rank + ">");
System.out.println("Size <" + p.size + ">");
}
});
panel.add(jb1);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
Let the number of processes be 3
Rank:0
Size:3
Rank:2
Size:3
Rank:1
Size:3
Not:
Rank:0
Size:3
I want all the ranks to be shown.
Related
I need a running order of pages 1-5 pages. I am using the card layout to navigate between each page after entering data on each page. The navigation to the next page works via an Action Listener on each text field.
My question is how do I pass the input from each card/page to the next? I can System.out.println each TextFeilds data. But I can't grab this information in the next card/action listener. The reason I need this to happen is I'd like to compare the strings of each page and also display a label of page 1's input on page/card2.
I apologize in advance for the massive block of code... Most of you will recognise most of this code anyway as it's copied from the CardLayout sample java code. I have just added two cards just now until I get the basics of passing variables back and fourth.
All help is appreciated even a small push the the right direction.
import java.awt.*;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Scanner;
import javax.swing.*;
public class CardLayoutDemo implements ItemListener {
JPanel cards; //a panel that uses CardLayout
final static String TEXTPANEL = "Card1 with text";
final static String TEXTPANEL2 = "Card with JTextField";
public void addComponentToPane(Container pane) {
//Put the JComboBox in a JPanel to get a nicer look.
JPanel comboBoxPane = new JPanel(); //use FlowLayout
String comboBoxItems[] = { TEXTPANEL, TEXTPANEL2};
JComboBox cb = new JComboBox(comboBoxItems);
cb.setEditable(false);
cb.addItemListener(this);
comboBoxPane.add(cb);
//Create the "cards".
JPanel card1 = new JPanel();
JTextField jtf=new JTextField("", 40);
jtf.setSize(40, 10);
card1.add(jtf);
JLabel lab1 = new JLabel("Page1 Text", JLabel.LEFT);
card1.add(lab1 = new JLabel("Page1"));
JPanel card2 = new JPanel();
JTextField jtf2=new JTextField("", 40);
jtf2.setSize(40, 10);
card2.add(jtf2);
JLabel lab2 = new JLabel("Page2 Text", JLabel.LEFT);
card2.add(lab2 = new JLabel("Page2 "));
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, TEXTPANEL);
cards.add(card2, TEXTPANEL2);
pane.add(cards, BorderLayout.CENTER);
jtf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String getText1 = jtf.getText();
System.out.println("PAGE1 ");
System.out.println(getText1);
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, TEXTPANEL2);
jtf2.requestFocus();
jtf2.requestFocusInWindow();
}
//JOptionPane.showMessageDialog(null,"Action Listener is working");
});
//PAGE2
jtf2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String getText2 = jtf2.getText();
System.out.println("PAGE2 ");
System.out.println(getText2);
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, TEXTPANEL);
jtf.requestFocus();
jtf.requestFocusInWindow();
jtf.setText("");
}
});
}//ADD COMPONENT TO PANE
public void itemStateChanged(ItemEvent evt) {
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, (String)evt.getItem());
// String getLoginUser1 = jtf.getText();
//System.out.println(getLoginUser1);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("CardLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(600, 300));
JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the content pane.
CardLayoutDemo demo = new CardLayoutDemo();
demo.addComponentToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
/* Use an appropriate Look and Feel */
try {
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
/* Turn off metal's use of bold fonts */
UIManager.put("swing.boldMetal", Boolean.FALSE);
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Here is another view on the problem. You could create some kind of cards manager and hold all required info inside of it. Here is an example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class CardLayoutDemo implements ItemListener {
private static class QuizManager {
final java.util.List<String> quizData = new ArrayList<>();
final java.util.List<JPanel> cards = new ArrayList<>();
final JPanel rootView;
public QuizManager(JPanel root){
rootView = root;
}
private JPanel createQuizPanel(String pageText, final int index) {
JPanel card = new JPanel();
JTextField jtf=new JTextField("", 40);
jtf.setSize(40, 10);
JLabel prev = new JLabel("", JLabel.LEFT);
card.add(prev);
card.add(jtf);
card.add(new JLabel(pageText, JLabel.LEFT));
jtf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
QuizManager.this.onCardSubmited(card, index, jtf.getText());
}
});
card.addComponentListener(new ComponentAdapter() {
#Override
public void componentShown(ComponentEvent e) {
super.componentShown(e);
jtf.requestFocus();
jtf.requestFocusInWindow();
String text = QuizManager.this.getPrevStringFor(index);
if (text != null) {
prev.setText(text);
}
}
});
return card;
}
private String getPrevStringFor(int index) {
if (index == 0) return null;
return quizData.get(index-1);
}
private String buildPanelName(int index) {
return String.format("card-%d", index);
}
public QuizManager addCard(String title) {
int index = cards.size();
quizData.add(null);//not set yet, just allocating
JPanel card = createQuizPanel(title, index);
cards.add(card);//this array looks like redundant
rootView.add(card, buildPanelName(index));
return this;
}
private void showCard(int index) {
CardLayout cl = (CardLayout) (rootView.getLayout());
cl.show(rootView, buildPanelName(index));
}
public void show() {
showCard(0);
}
public void onCardSubmited(JPanel card, int cardIndex, String text) {
System.out.println("page " + cardIndex);
System.out.println("text : " + text);
quizData.set(cardIndex, text);
if (cardIndex < cards.size() - 1) {
showCard(cardIndex + 1);
} else {
System.out.println("WE FINISHED");
//add finalazing code here
}
}
}
JPanel cardsRoot;
public void addComponentToPane(Container pane) {
cardsRoot = new JPanel(new CardLayout());
QuizManager manager = new QuizManager(cardsRoot)
.addCard("First page")
.addCard("Second page")
.addCard("Third card")
.addCard("Forth card");
pane.add(cardsRoot, BorderLayout.CENTER);
manager.show();
}
public void itemStateChanged(ItemEvent evt) {
CardLayout cl = (CardLayout)(cardsRoot.getLayout());
cl.show(cardsRoot, (String)evt.getItem());
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("CardLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(600, 300));
JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the content pane.
CardLayoutDemo demo = new CardLayoutDemo();
demo.addComponentToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
/* Use an appropriate Look and Feel */
try {
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
/* Turn off metal's use of bold fonts */
UIManager.put("swing.boldMetal", Boolean.FALSE);
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Take a look how easy would be to create many of cards.
You've got the variable declaration of key components buried within the addComponentToPane(...) method, limiting their scope to this method only, preventing you from getting the information you need. While the canonical solution for this sort of problem is to use an model-view-controller or MVC type pattern so that the model (the underlying program logic and data) is extracted out of the view (the GUI), you can do a quick and dirty solution just by giving your variables private class scope.
For instance, if the JTextField was called textField and was held in a JPanel that acts as a "card", say called cardPanel, you could create a class that looked something like so:
public class CardPanel extends JPanel {
// constants to give the GUI a bigger size
private static final int PREF_W = 300;
private static final int PREF_H = 100;
// our key JTextField declared at class level
private JTextField textField = new JTextField(20);
// a JLabel to display the previous cardpanel's text
private JLabel label = new JLabel(" ");
// create the JPanel
public CardPanel(String name) {
setName(name);
setBorder(BorderFactory.createTitledBorder("Panel " + name));
JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
labelPanel.add(new JLabel("Prior Card's Word: "));
labelPanel.add(label);
setLayout(new BorderLayout());
add(textField, BorderLayout.PAGE_START);
add(labelPanel, BorderLayout.CENTER);
}
// have to jump through this hoop if we want to JTextField to
// have focus when a card is swapped
public void setFocusOnTextField() {
textField.requestFocusInWindow();
textField.selectAll();
}
// to make our GUI larger
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
// allow outside classes to add a listener to the JTextField
public void addActionListener(ActionListener listener) {
textField.addActionListener(listener);
}
// allow outside classes to get text from the text field
public String getTextFieldText() {
return textField.getText();
}
// allow outside classes to put text into the JLabel
public void setLabelText(String text) {
label.setText(text);
}
}
And then we could use it like so:
public class MyCardLayoutDemo extends JPanel {
private static final String[] NAMES = {"One", "Two", "Three", "Four"};
private Map<String, CardPanel> namePanelMap = new HashMap<>();
private CardLayout cardLayout = new CardLayout();
private int nameIndex = 0;
public MyCardLayoutDemo() {
setLayout(cardLayout);
MyListener listener = new MyListener();
for (String name : NAMES) {
CardPanel cardPanel = new CardPanel(name);
cardPanel.addActionListener(listener);
add(cardPanel, name);
namePanelMap.put(name, cardPanel);
}
}
private class MyListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// get the current CardPanel
String name = NAMES[nameIndex];
CardPanel currentCard = namePanelMap.get(name);
// advance the name index to get the next CardPanel
nameIndex++;
nameIndex %= NAMES.length;
name = NAMES[nameIndex];
CardPanel nextCard = namePanelMap.get(name);
// get text from current CardPanel
String text = currentCard.getTextFieldText();
nextCard.setLabelText(text); // and put it into next one
// swap cards
cardLayout.show(MyCardLayoutDemo.this, name);
nextCard.setFocusOnTextField();
}
}
private static void createAndShowGui() {
MyCardLayoutDemo mainPanel = new MyCardLayoutDemo();
JFrame frame = new JFrame("My CardLayout Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
I have very simple code, just 2 buttons to display numbers from array in textArea.
public class FotyUI extends javax.swing.JFrame {
public FotyUI() {
initComponents();
}
int[] numbers = {0,1,2,3,4,5,6,7,8,9};
int position = 0;
private void nextActionPerformed(java.awt.event.ActionEvent evt) {
position ++;
tekst.setText(" " + numbers[position]);
}
private void previousActionPerformed(java.awt.event.ActionEvent evt) {
position--;
tekst.setText(" " + numbers[position]);
}
Now, this code runs great I have two buttons and textArea, but I would like to create an external JFrame2 with 2 buttons to control/display array from Frame 1
When I type:
public class FotyUI extends javax.swing.JFrame {
public FotyUI() {
initComponents();
}
int[] numbers = {0,1,2,3,4,5,6,7,8,9};
int position = 0;
JFrame temp = new JFrame();
JPanel panelik = new JPanel();
JButton nextS = new JButton("Next");
JButton prevS = new JButton("Previous");
panelik.add(nextS);
I have an error to create package panelik....
Can u help me ? How to create Frame 2 with 2 buttons and textArea to display/control content of array from Frame1
ok, I solve it !!!!!!!!
JFrame frame = new JFrame("Test");
frame.setVisible(true);
frame.setSize(500,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
JButton button = new JButton("hello agin1");
panel.add(button);
pole = new JTextField();
panel.add(pole);
button.addActionListener (new Action1());
static class Action1 implements ActionListener {
public void actionPerformed (ActionEvent e) {
position ++;
tekst.setText(" " + numbers[position]);
pole.setText(" " + numbers[position]);
}
}
I'd like to create a new window which is used in POS system. The user input is for an amount of money the customer has and the window has to display the exchange amount. I'm new with JOptionPane feature (I have been using JAVAFX and it's different).
This is my code:
public static void main(String[] argv) throws Exception {
String newline = System.getProperty("line.separator");
int cost = 100;
int amount = Integer.parseInt(JOptionPane.getText()) // this is wrong! This needs to come from user input box in the same window.
JFrame frame = new JFrame();
String message = "Enter the amount of money"+newline+"The exchange money is: "+amount-cost;
String text = JOptionPane.showInputDialog(frame, message);
if (text == null) {
// User clicked cancel
}
Is there any suggestion?
use InputDialog for get userinput
public static void main(String[] argv) throws Exception {
//JFrame frame = new JFrame();
//frame.setVisible(true);
int cost = 100;
JLabel l=new JLabel("The exchange money is");
JPanel p=new JPanel(new GridLayout(1, 2, 10, 10));
p.setPreferredSize(new Dimension(400, 50));
JTextField t=new JTextField("Enter the amount of money");
t.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
try{
int amount=Integer.parseInt(t.getText());
l.setText("The exchange money is: \n" + (amount - cost));
}catch(Exception ex){
// ex.printStackTrace();
}
}
});
p.add(t);
p.add(l);
int option = JOptionPane.showConfirmDialog(null,p,"JOptionPane Example : ",JOptionPane.OK_CANCEL_OPTION,JOptionPane.PLAIN_MESSAGE);
if(option==0){
System.out.println("ok clicked");
}else{
System.out.println("cancel clicked");
}
}
What you need to do, is to create your own custom JOptionPane, that has it's own components, instead of using the build in one's.
Place a JTextField in it, and add a DocumentListener to that, so that when you change something on it, it can be reciprocated on to the status label, as need be.
Try this small example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class JOptionPaneExample {
private JLabel label;
private JTextField tfield;
private JLabel statusLabel;
private static final int GAP = 5;
private void displayGUI() {
JOptionPane.showMessageDialog(null, getPanel());
}
private JPanel getPanel() {
JPanel panel = new JPanel(new GridLayout(0, 1));
label = new JLabel("Enter something: ", JLabel.CENTER);
tfield = new JTextField(10);
tfield.getDocument().addDocumentListener(new MyDocumentListener());
JPanel controlPanel = new JPanel();
controlPanel.add(label);
controlPanel.add(tfield);
panel.add(controlPanel);
statusLabel = new JLabel("", JLabel.CENTER);
panel.add(statusLabel);
return panel;
}
private class MyDocumentListener implements DocumentListener {
#Override
public void changedUpdate(DocumentEvent de) {
updateStatus();
}
#Override
public void insertUpdate(DocumentEvent de) {
updateStatus();
}
#Override
public void removeUpdate(DocumentEvent de) {
updateStatus();
}
private void updateStatus() {
statusLabel.setText(tfield.getText());
}
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new JOptionPaneExample().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
Try using this:
if( myJOptionPane.getValue() instanceOf String){
String myString = (String) myJOptionPane.getValue();
}
Then use the result of myString to do whatever you intend to do.
I'm trying to create a hangman game and so far it's coming along GREAT, but the layout design just doesn't seem to fall into place! The alphabet is supposed to end up in a FlowLayout order on top of the Hangman picture with the buttons "Restart", "Help" "Add New Word" and "Exit" at the bottom! What am I doing wrong?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class Hangman extends JFrame
{
int i = 0;
static JPanel panel;
static JPanel panel2;
static JPanel panel3;
public Hangman()
{
JButton[] buttons = new JButton[26];
panel = new JPanel(new FlowLayout());
panel2 = new JPanel();
panel3 = new JPanel();
JButton btnRestart = new JButton("Restart");
btnRestart.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
}
});
JButton btnNewWord = new JButton("Add New Word");
btnNewWord.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
try
{
FileWriter fw = new FileWriter("Words.txt", true);
PrintWriter pw = new PrintWriter(fw, true);
String word = JOptionPane.showInputDialog("Please enter a word: ");
pw.println(word);
pw.close();
}
catch(IOException ie)
{
System.out.println("Error Thrown" + ie.getMessage());
}
}
});
JButton btnHelp = new JButton("Help");
btnHelp.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String message = "The word to guess is represented by a row "
+ "of dashes, giving the number of letters and category of "
+ "the word. \nIf the guessing player suggests a letter "
+ "which occurs in the word, the other player writes it "
+ "in all its correct positions. \nIf the suggested "
+ "letter does not occur in the word, the other player "
+ "draws one element of the hangman diagram as a tally mark."
+ "\n"
+ "\nThe game is over when:"
+ "\nThe guessing player completes the word, or guesses "
+ "the whole word correctly"
+ "\nThe other player completes the diagram";
JOptionPane.showMessageDialog(null,message, "Help",JOptionPane.INFORMATION_MESSAGE);
}
});
JButton btnExit = new JButton("Exit");
btnExit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
ImageIcon icon = new ImageIcon("D:\\Varsity College\\Prog212Assign1_10-013803\\images\\Hangman1.jpg");
JLabel label = new JLabel();
label.setIcon(icon);
String b[]= {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
for(i = 0; i < buttons.length; i++)
{
buttons[i] = new JButton(b[i]);
panel.add(buttons[i]);
}
panel2.add(label);
panel3.add(btnRestart);
panel3.add(btnNewWord);
panel3.add(btnHelp);
panel3.add(btnExit);
}
public static void main(String[] args)
{
Hangman frame = new Hangman();
frame.add(panel, BorderLayout.NORTH);
frame.add(panel2, BorderLayout.CENTER);
frame.add(panel3, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
Here are a few suggestions:
Use a GridLayout for the top panel; in this case, zero means the number of rows is determined by the specified number of columns and the total number of components in the layout:
JPanel north = new JPanel(new GridLayout(0, 9));
Here's an outline of how you can make your center panel have a reasonable initial size; note how you can draw relative to the current size:
JPanel center = new JPanel() {
private static final int N = 256;
private static final String S = "Todo...";
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int dx = (getWidth() - g.getFontMetrics().stringWidth(S)) / 2;
int dy = getHeight() / 2;
g.drawString(S, dx, dy);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(N, N);
}
};
You can construct your button names like this:
for (int i = 0; i < 26; i++) {
String letter = String.valueOf((char) (i + 'A'));
buttons[i] = new JButton(letter);
north.add(buttons[i]);
}
Make your panels instance variables and start on the event dispatch thread:
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Hangman frame = new Hangman();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.add(frame.north, BorderLayout.NORTH);
frame.add(frame.center, BorderLayout.CENTER);
frame.add(frame.south, BorderLayout.SOUTH);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
This problem is pretty well documented if you do some research - it seems all the panels (besides the CENTER one) aren't recalculated when resized. See How do I make this FlowLayout wrap within its JSplitPane? and http://www.velocityreviews.com/forums/t608472-wrap-flowlayout.html
But for a really quick fix, try changing your main method to this... (basically using a BoxLayout as your main container)
public static void main(String[] args)
{
TempProject frame = new TempProject();
Box mainPanel = Box.createVerticalBox();
frame.setContentPane(mainPanel);
mainPanel.add(panel);
mainPanel.add(panel2);
mainPanel.add(panel3);
frame.pack();
frame.setVisible(true);
}
For architecture and design purposes I would like to design my GUI with a class for each card in a Java Swing CardLayout. and then have a mainapp that builds the GUI. I am having trouble doing this right now.
I would like to example have a class for the main menu with all the button locations etc. and then just instantiate that card and add it to the layout in another class. Does anyone know how to achieve this?
Perhaps you want to give your class that uses the CardLayout a public loadCard method, something like
public void loadCard(JComponent component, String key) {
cardHolderPanel.add(component, key);
}
where cardHolderPanel is the container that holds the cards.
Since your creating classes to act as cards, consider having them all extend from a base abstract class or an interface that has a method that allows this class to hold its own key String. Either that or simply use the JComponent name property to have a component hold its own key String, one that can easily be obtained via getName().
For a more detailed answer, you may need to give us more details on your current application and its structure.
very simple example that held Swing Objects generated from different Java Classes
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class OnTheFlyImageTest extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel cardPanel;
private CardLayout cardLayout;
public OnTheFlyImageTest() {
JPanel cp = new JPanel(new BorderLayout());
cp.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
cardLayout = new CardLayout(5, 5);
cardPanel = new JPanel(cardLayout);
cp.add(cardPanel);
for (int i = 0; i < 100; i++) {// Create random panels for testing.
String name = "ImagePanel" + (i + 1);
String image = (i & 1) == 0 ? "foo.gif" : "bar.gif";
ImagePanel imgPanel = new ImagePanel(name, image);
cardPanel.add(imgPanel, name);
cardLayout.addLayoutComponent(imgPanel, name);
}
JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 5, 5));
JButton prevButton = new JButton("< Previous");
prevButton.setActionCommand("Previous");
prevButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.previous(cardPanel);
}
});
buttonPanel.add(prevButton);
JButton nextButton = new JButton("Next >");
nextButton.setActionCommand("Next");
nextButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.next(cardPanel);
}
});
buttonPanel.add(nextButton);
JPanel temp = new JPanel(new BorderLayout());
temp.add(buttonPanel, BorderLayout.LINE_END);
cp.add(temp, BorderLayout.SOUTH);
setContentPane(cp);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Test");
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new OnTheFlyImageTest().setVisible(true);
}
});
}
}
class ImagePanel extends JPanel {
private static final long serialVersionUID = 1L;
private String imgString;
private JLabel imgLabel;
public ImagePanel(String name, String imgString) {
setName(name);
this.imgString = imgString;
setLayout(new BorderLayout());
// Ensure size is correct even before any image is loaded.
setPreferredSize(new Dimension(640, 480));
}
#Override
public void setVisible(boolean visible) {
if (visible) {
System.err.println(getName() + ": Loading and adding image");
ImageIcon icon = new ImageIcon(imgString);
imgLabel = new JLabel(icon);
add(imgLabel);
}
super.setVisible(visible);
if (!visible) { // Do after super.setVisible() so image doesn't "disappear".
System.err.println(getName() + ": Removing image");
if (imgLabel != null) { // Before display, this will be null
remove(imgLabel);
imgLabel = null; // Hint to GC that component/image can be collected.
}
}
}
}