Jtabbedpane layout for button does not work - java

The below swing interface using tabbedpane works fine until i set layout for button, that is when i set the content pane loginpage to null (loginpage.setlayout(null)) the buttons disappear from the pane but works when i replace button with textfield or textarea.
package atmg;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
public class newgui extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public JPanel clickfn= new JPanel(),gui= new JPanel(),trasgui= new JPanel(),contentpanel = new JPanel();
public static JTabbedPane Tabs = new JTabbedPane();
public JButton loginpage, filloginfo,createlogin ;
public JLabel label1 ,label2;
private CardLayout cardlayout = new CardLayout();
//static JPanel panel1 = new JPanel();
newguilogin nw;
public static void main(String[] args) {
newgui tf = new newgui();
tf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tf.setSize(700,700);
tf.setVisible(true);
tf.setLocation(400,20);
}
public newgui(int a)
{
System.out.println(a);
}
public newgui() {
super("ATM");
Initialize();
}
public void Initialize()
{
nw= new newguilogin();
nw.setgui(this);
loginpage = new JButton("Go to loginpage");
filloginfo = new JButton("go to fill log info");
createlogin = new JButton("create a new user");
// TODO Auto-generated constructor stub
actionListener a1 = new actionListener();
loginpage.addActionListener(a1);
filloginfo.addActionListener(a1);
createlogin.addActionListener(a1);
clickfn.add(loginpage);
clickfn.setSize(20,20);
clickfn.setLocation(50,50);
clickfn.add(filloginfo);
contentpanel.setLayout(cardlayout);
contentpanel.add(Tabs, "tab");
Tabs.add(clickfn,"panel1");
//Tabs.add(trasgui,"panel3");
this.setContentPane(contentpanel);
cardlayout.show(contentpanel, "tab");
}
public class actionListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JButton src = (JButton)e.getSource();
if(src.equals(loginpage))
//threader = new Threading();
//Tabs.addTab("panel2", gui);
nw = new newguilogin();
nw.initialize();
}
}
}

that is when i set the content pane loginpage to null (loginpage.setlayout(null)) the buttons disappear
A good rule of thumb to follow with Swing layouts: never use null layouts.
While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
Understand also that you can nest JPanels, each using its own simple layouts, and thereby create complex GUI's with simple layout managers.

Related

Java Card Layouts using Choice

I want to create a program with a GUI where I have a Choice with three different options.
I have to realize it with CardLayout but my problem is that I don't know how to switch the CardLayoutPanel to the one I selected in the Choice.
Choice ch = new Choice();
Panel cl = new Panel(new CardLayout());
Panel one = new Panel();
Panel two = new Panel();
Panel three = new Panel();
and in the constructor I have:
// CARD LAYOUT PANELS
cl.add(one, "1");
cl.add(two, "2");
cl.add(three, "3");
f.setLayout(new FlowLayout());
// CHOICE-OPTIONS
ch.add("one");
ch.add("two");
ch.add("three");
How can I add an ActionListener to switch between the different Panels using the Choice ?
(Please don't comment google it - I already did, otherwise I wouldn't ask)
Thank you!
Here is a SSCCE (Short Self Contained Correct Example). Notes after the code.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Choice;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class AwtTest0 extends WindowAdapter implements ItemListener {
private Frame frame;
private Panel cards;
public void itemStateChanged(ItemEvent event) {
CardLayout layout = (CardLayout) cards.getLayout();
if (event.getStateChange() == ItemEvent.SELECTED) {
Object obj = event.getItem();
String name = obj.toString();
layout.show(cards, name);
}
}
public void windowClosing(WindowEvent event) {
System.exit(0);
}
private Panel createCard(String text) {
Panel card = new Panel();
Label label = new Label(text);
card.add(label);
return card;
}
private Panel createCards() {
cards = new Panel(new CardLayout());
cards.add(createCard("1"), "one");
cards.add(createCard("2"), "two");
cards.add(createCard("3"), "three");
return cards;
}
private Panel createChoice() {
Panel panel = new Panel();
Choice ch = new Choice();
ch.add("one");
ch.add("two");
ch.add("three");
ch.addItemListener(this);
panel.add(ch);
return panel;
}
private void showGui() {
frame = new Frame();
frame.addWindowListener(this);
frame.add(createChoice(), BorderLayout.PAGE_START);
frame.add(createCards(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
final AwtTest0 instance = new AwtTest0();
EventQueue.invokeLater(() -> instance.showGui());
}
}
In method main I call method invokeLater which explicitly launches the EDT (Event Dispatch Thread). The GUI must run on this thread.
In order to cause the application to terminate when you click the close window button (which is usually an X in the top corner of the window), you add a WindowListener.
When you add components to the Frame, you are actually adding them to the content pane which is a Panel that has BorderLayout layout manager.
Choice does not support ActionListener, it supports ItemListener. Hence the above code implements ItemListener.

How to call a panel from a button with ActionListener

So I'm making a simple program that jumps from panel to panel and am using an actionlistener Button to make the jump. What kind of method or operation do I use to jump from panel to panel?
I tried to use setVisible(true); under the action listener, but I get just a blanks screen. Tried using setContentPane(differentPanel); but that doesn't work.
ackage Com.conebind.Characters;
import Com.conebind.Tech.TechA16;
import Com.conebind.Overviews.OverviewA16;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Char_A16 extends JFrame {
private JButton combosButton16;
private JButton techButton16;
private JButton overviewButton16;
private JLabel Image16;
private JPanel panel16;
private JPanel panelOverviewA16;
public Char_A16() {
overviewButton16.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
OverviewA16 overview16 = new OverviewA16();
overview16.setVisible(true);
overview16.pack();
overview16.setContentPane(new Char_A16().panelOverviewA16);
}
});
techButton16.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//Todo
}
});
}
private void createUIComponents(){
Image16 = new JLabel(new ImageIcon("Android 16.png"));
}
public static void main (String[] args){
JFrame frame = new JFrame("Android 16");
frame.setContentPane(new Char_A16().panel16);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);}
}
The setContentPane(OverviewA16) doesn't work because there's not an object that defines the panel.
Please check this demo project showing how to use CardLayout with IntelliJ IDEA GUI Designer.
The main form has a method that switches between 2 forms displayed inside it:
public void showPanel(String id) {
final CardLayout cl = (CardLayout) cardPanel.getLayout();
cl.show(cardPanel, id);
}
Both forms are added to the card layout during the main form initialization:
FormOne one = new FormOne();
one.setParentForm(this);
cardPanel.add(one.getPanel(), FORM_ONE);
FormTwo two = new FormTwo();
two.setParentForm(this);
cardPanel.add(two.getPanel(), FORM_TWO);
final CardLayout cl = (CardLayout) cardPanel.getLayout();
cl.show(cardPanel, FORM_ONE);
A reference to the main parent form is passed to these 2 forms using setParentForm() method so that FormOne and FormTwo classes can access the showPanel() method of the MainForm.
In a more basic case you may have a button or some other control that switches the forms
located directly on the MainForm, then you may not need passing the main form reference to the subforms, but it can be still useful depending on your app logic.

Change attribute in other jframe when a button is clicked in another JFrame

I have 2 jframes, 1 is kinda like the main menu, i want an attribute to change in the level jframe when a button is pressed so i tried:
SpeelVeld frame = new SpeelVeld();
frame.level = 1;
System.out.println(frame.level);
I used the sout to see what really happens because it wasnt working, but i see that the level goes from 0 to 1 back to 0 and goes on and on, does someone know why and how to fix?
SpeelVeld frame = new SpeelVeld();
frame.setBounds(0,0,519,591);
frame.setLocationRelativeTo(null);
frame.getContentPane().setBackground(Color.WHITE);
frame.setTitle("RWINA");
frame.setVisible(true);
frame.setLevel(1);
this is in the main method of my original GameProject file.
How can i make a jdialog
I have 2 jframes, 1 is kinda like the main menu,
You shouldn't use 2 JFrames for this. The dependent sub-window, likely your main menu window, should in fact be a JDialog, probably a non-modal dialog from the looks of it.
I want an attribute to change in the level jframe when a button is pressed so i tried:
SpeelVeld frame = new SpeelVeld();
frame.level = 1;
System.out.println(frame.level);
and here's a big problem. Understand that in this code, you're creating a new SpeelVeld object, the stress being on the word new. Changing the state of this object will have no effect on the other SeelVeld object that is currently being displayed. Do do that, your second window will need a valid reference to the displayed SeelVeld object. How to do this will depend all on code not yet shown, but often it can be done simply by passing in the displayed SpeelVeld object into the main menu object by use of a constructor parameter or setter method.
For example:
import java.awt.Dialog.ModalityType;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
// JPanel for our main GUI
public class SpeelVeldFoo {
private static void createAndShowGui() {
// JPanel used by the main JFrame
SpeelVeldPanel speelVeldPanel = new SpeelVeldPanel();
// JPanel used by the main menu JDialog. Pass the above into it
MainMenuPanel mainMenuPanel = new MainMenuPanel(speelVeldPanel);
// create your JFrame
JFrame frame = new JFrame("Speel Veld");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(speelVeldPanel); // add the JPanel
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
// create your non-modal JDialog
JDialog menuDialog = new JDialog(frame, "Main Menu", ModalityType.MODELESS);
menuDialog.add(mainMenuPanel); // add the JPanel that holds its "guts"
menuDialog.pack();
menuDialog.setLocationByPlatform(true);
menuDialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
#SuppressWarnings("serial")
class SpeelVeldPanel extends JPanel {
private int level = 1; // simple example just has a level int
private JLabel levelLabel = new JLabel("1"); // and displays it in a JLabel
public SpeelVeldPanel() {
add(new JLabel("Level:"));
add(levelLabel);
int ebGap = 50;
setBorder(BorderFactory.createEmptyBorder(ebGap, 2 * ebGap, ebGap, 2 * ebGap));
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
// whenever level is changed, update the display
this.level = level;
levelLabel.setText(String.valueOf(level));
}
}
// class for the JPanel held by the JDialog
#SuppressWarnings("serial")
class MainMenuPanel extends JPanel {
private JSpinner levelSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 5, 1));
private SpeelVeldPanel speelVeldPanel = null; // reference to the main GUI
// note the parameter.... you pass in the displayed main GUI so you can
// change it
public MainMenuPanel(final SpeelVeldPanel speelVeldPanel) {
this.speelVeldPanel = speelVeldPanel; // set the field
// respond when the spinner's data changes
levelSpinner.addChangeListener(new LevelListener());
add(new JLabel("Set the Speel Veld's level:"));
add(levelSpinner);
int ebGap = 10;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
}
private class LevelListener implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
// when the spinner's data changes
int level = (int) levelSpinner.getValue(); // get the data
speelVeldPanel.setLevel(level); // and send it to the main GUI
}
}
}
You'll note that I don't like extending JFrame or JDialog if I can avoid it. My feeling is that one can paint oneself into a corner by having your class extend JFrame, forcing you to create and display JFrames, when often more flexibility is called for. More commonly your GUI classes will be geared towards creating JPanels, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via CardLayouts, wherever needed. This will greatly increase the flexibility of your GUI coding.
You probably want the JFrame to be the top-level container, then have a JPanel that holds your menu. The menu could be whatever you want, I'm using a JTextArea. Then, you need a JButton for the JPanel or JFrame that when pressed, changes the text in the JTextArea. Here is an implementation that you could work from. I'm using the ActionEvent as the trigger for when to mess with the JTextArea:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class SimpleSwing {
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
JPanel mainMenuPanel = new JPanel();
JTextArea textAttribute = new JTextArea("Original Text");
JButton changeAttributeButton = new JButton("Change Attribute");
changeAttributeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textAttribute.setText("Whatever new text you want");
}
});
mainMenuPanel.add(textAttribute);
mainMenuPanel.add(changeAttributeButton);
mainFrame.add(mainMenuPanel);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(500, 500);
mainFrame.setVisible(true);
}
}

How to reference JFrame

I have a problem which is most likely "simple" however I can't figure it out. I am trying to reference my current JFrame so that I can dispose of it, and create a new one, thus "resetting" the program, however I and having trouble figuring out how to reference the JFrame, I have tried, super, this and getParent(), but none of the seem to work. Thanks for any / all help. ^^
Here is my code:
Main Class, just sets up the Jframe and calls the class that creates everything:
public static void main(String args[]) {
JFrame window = new JFrame();
Director director = new Director(window, args);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.pack();
window.setVisible(true);
}
}
Class the creates everything:
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class Director extends JFrame implements CollisionListener {
private BrickWall wall;
private JLabel gameTitle, gameScore, gameLives;
private JPanel controlPanel;
private JButton reset, quit;
private JRadioButton hard, normal, easy;
private int score = 6, lives = 5;
private ButtonGroup difficulty;
public Director(JFrame window, String[] args) {
window.getContentPane().add(makeGamePanel(), BorderLayout.CENTER);
window.getContentPane().add(gameControlPanel(), BorderLayout.NORTH);
}
public void collisionDetected(CollisionEvent e) {
wall.setBrick(e.getRow(), e.getColumn(), null);
}
private JComponent makeGamePanel() {
wall = new BrickWall();
wall.addCollisionListener(this);
wall.buildWall(3, 6, 1, wall.getColumns(), Color.GRAY);
return wall;
}
// Reset method I'm trying to dispose of the JFrame in.
private void reset() {
JFrame frame = new JFrame();
frame.getContentPane().add(makeGamePanel(), BorderLayout.CENTER);
frame.getContentPane().add(gameControlPanel(), BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private JComponent gameControlPanel() {
// CONTROL PANEL PANEL!
controlPanel = new JPanel();
gameTitle = new JLabel("Brickles");
gameScore = new JLabel("Score:" + " " + score);
gameLives = new JLabel("Lives:" + " " + lives);
reset = new JButton("Reset");
quit = new JButton("Quit");
hard = new JRadioButton("Hard", false);
normal = new JRadioButton("Normal", true);
easy = new JRadioButton("Easy", false);
difficulty = new ButtonGroup();
difficulty.add(hard);
difficulty.add(normal);
difficulty.add(easy);
controlPanel.setLayout(new GridLayout(4, 2));
controlPanel.add(gameTitle);
controlPanel.add(gameScore);
controlPanel.add(hard);
controlPanel.add(gameLives);
controlPanel.add(normal);
controlPanel.add(reset);
controlPanel.add(easy);
controlPanel.add(quit);
// Action Listener, where I'm caling the reset method.
reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
reset();
}
});
return controlPanel;
}
}
You can refer to the "outer this" from a nested class with the following syntax:
reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Director.this.reset();
}
});
Yes, you can refer to the outer class by specifying it with the class name as noted in DSquare's good answer (1+ to it), but I urge you not to fling JFrame's at the user as you're program is trying to do. I recommend:
Instead of opening and closing multiple JFrames, use only one JFrame as the main application's window.
If you need helper windows, such as modal windows to get critical information that is absolutely needed, before the program can progress, use modal dialogs such as JDialogs or JOptionPanes.
If you need to swap GUI's, instead of swapping JFrames, swap "views" inside the JFrame via a CardLayout.
Gear your code towards creating these JPanel views and not JFrames as it will make your Swing GUI's much more flexible and portable.

the components of the tabs are not shown

I have written the following code but the components of tabs are not shown....in fact I want to create tabs dynamically when I enter something in the text-box...the created tabs should contain a new text-field and button. this code is a sample and after it is completed I have another question.
please let me know where I have made mistake.
package test;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
public class TestingTab extends JFrame {
private JTextField jTextField1;
private JButton jButton1;
static ArrayList<JPanel> ary = new ArrayList<JPanel>();
private int tabIndex=0;
static int index=0;
private JTabbedPane tabbedPane;
/**
* #param args
*/
public TestingTab(){
super("Testing Tab Frame");
setLayout(null);
Handler but1 = new Handler();
jTextField1 = new JTextField();
jTextField1.setVisible(true);
jTextField1.setBounds(12, 12, 85 , 30);
add(jTextField1);
jButton1 = new JButton("Button1");
jButton1.setVisible(true);
jButton1.setBounds(130, 12, 85, 30);
add(jButton1);
jButton1.addActionListener(but1);
tabbedPane = new JTabbedPane();
tabbedPane.setBounds(12, 54, 200, 220);
tabbedPane.setVisible(false);
add(tabbedPane);
pack();
setSize(250,110);
}
private class Handler implements ActionListener{
public void actionPerformed(ActionEvent evt){
String input = jTextField1.getText();
setSize(250,330);
JPanel inst = createPanel(input);
inst.setVisible(true);
tabbedPane.addTab(Integer.toString(tabIndex), inst);
tabbedPane.setVisible(true);
}
}
protected JPanel createPanel(String input){
JPanel inst = new JPanel();
inst.setVisible(true);
inst.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED),input));
JTextField textField = new JTextField();
textField.setVisible(true);
JButton button = new JButton();
button.setVisible(true);
inst.setLayout(null);
inst.add(button);
inst.add(textField);
ary.add(inst);
tabIndex=index;
index++;
return inst;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TestingTab inst = new TestingTab();
inst.setVisible(true);
}
}
You're using null layout when creating a panel. That's the reason the components are not displayed. When layout property is null, the container uses no layout manager. This is called absolute positioning. In case of absolute positioning you must specify size and location of components. Absolute positing approach has many drawbacks and should be taken into consideration with care. Null layouts should/can be avoided in most cases.
Remove inst.setLayout(null); and you will see the button and text field.
Check out A Visual Guide to Layout Managers and Using Layout Managers for more details on layout managers.

Categories

Resources