JTabbedPane with 2 tabs is not showing up - java

I am creating a program in which when a person click on label it will take you to a 2nd panel which will have 2 tabs. The problem is when I click on image label I only see blank window with no tabs and nothing in it.
import java.awt.*;
import static java.awt.Font.BOLD;
import java.awt.event.*;
import java.awt.event.*;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.border.*;
import javax.swing.event.*;
public class hotels extends JFrame{
JButton hotel;
JLabel image;
JTabbedPane tabbed,tabbed1;
JPanel panel;
JPanel panel1;
Container pane;
public hotels(){
panel=new JPanel();
panel.setBackground(Color.cyan);
hotel=new JButton();
hotel.setText("Hotels");
Font myFont = new Font("Serif", Font.BOLD, 18);
hotel.setFont(myFont);
panel.setLayout(null);
panel.add(hotel);
hotel.setBounds(50, 80, 100, 40);
image=new JLabel();
image.setBounds(50,1,80,80);
image.setBorder(BorderFactory.createLineBorder(Color.yellow));
image.setBackground(Color.white);
image.setIcon(new ImageIcon("2.gif"));
panel.add(image);
panel1=new JPanel();
tabbed=new JTabbedPane();
tabbed.add( "Round Trip",panel1);
tabbed.add("One Way",panel1);
panel1.setVisible(false);
panel1.revalidate();
panel.revalidate();
panel1.repaint();
panel.repaint();
pane=getContentPane();
pane.add(tabbed);
pane.add(panel1);
pane.add(panel);
image.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
if (e.getSource()==image){
panel1.show();
panel.setVisible(false);
panel1.setVisible(true);
tabbed.setVisible(true);
}
}
});
}
public static void main(String[] args) {
hotels mw=new hotels();
mw.setVisible(true);
mw.setSize(400, 400);
}
}

pane.add(tabbed);
pane.add(panel1);
pane.add(panel);
The above code attempts to add 3 children to the Content pane's - the Content pane by default has a BorderLayout, which cannot have more than 1 component in it's CENTER position - hence the last Component added is the Component that will be seen. Your options are
Use a CardLayout which allows you to change the Panel shown dynamically
Remove all items from the appropriate Container, then add them and revalidate/repaint
Example of 1 in link above. Example of 2 (in the MouseListener):
pane.removeAll();
pane.add(tabbed);//presuming you want tabbed to show now
pane.revalidate();//or invalidate/validate for <1.7 JRE versions
pane.repaint();

There are a series of problems, including the use of null layouts, which will haunt you with no end of problems...
tabbed.add( "Round Trip",panel1);
tabbed.add("One Way",panel1);
The above code is adding the same panel to two different tabs, but since a component can only have a single parent, it will automatically remove the "Round Trip" tab
Then...
pane=getContentPane();
pane.add(tabbed);
pane.add(panel1);
pane.add(panel);
Which removes all the tabs from the tabbed lane (for the same reason above) and, depending on what layout manager your using, may only show panel
You don't need to change the visibility state of your components been managed by the JTabbedPane, as it will take care of all that for you
See How to Use Tabbed Panes for more details

Related

How do I get both my image and button to display?

Currently, the problem I am trying to solve is how I get both my image and button to show up.
When I have the following line in the code the image shows up but when I remove it my image doesn't display but the button does:
setLayout (new FlowLayout()) ;
without the line of code
with the line of code
Images for example ^
import java.awt.*;
public class Panel extends JFrame {
private ImageIcon FirstPageImage;
private JLabel FirstPageLabel;
private JLayeredPane SignupButtonLayer;
private JButton Button;
public Panel(){
setLayout (new FlowLayout()) ;
FirstPageImage = new ImageIcon(getClass().getResource("FirstPageAnimationUsing.gif"));
FirstPageLabel = new JLabel(FirstPageImage);
FirstPageImage.setImage(FirstPageImage.getImage().getScaledInstance(343,820,Image.SCALE_DEFAULT));
add(FirstPageLabel);
Button = new JButton();
SignupButtonLayer = new JLayeredPane();
Button.setOpaque(true);
Button.setBackground(Color.cyan);
Button.setBounds(94,617,159,82);
SignupButtonLayer.add(Button, JLayeredPane.DEFAULT_LAYER);
add(SignupButtonLayer);
}
public static void main(String[] args) {
Panel gui = new Panel();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setVisible(true);
gui.pack();
gui.setTitle("Reminder App");
gui.setSize(360,850);
}
}
Refer to How to Use Layered Panes.
You need to give the JLayeredPane a preferred size. Since your JLayeredPane contains only a single JButton, that size should be big enough to display the entire JButton.
The arguments to method setBounds – that you call on Button – are relative to its container, i.e. SignupButtonLayer. Setting the x to 94 and the y to 617 means that Button is placed outside of the bounds of SignupButtonLayer. Hence you don't see it. In the below code, I set x and y both to 0 (zero) so that the top, left corner of Button aligns with the top, left corner of SignupButtonLayer.
No need to explicitly call method setOpaque(true) for Button since that is the default, anyway.
Either call pack() – which is usually preferred – or setSize() but don't call both.
setVisible(true) should be called only once your GUI is completely built. In the below code I call it after calling pack() and setTitle().
I suggest that you try to adhere to Java naming conventions.
I also suggest that try not to name your classes the same as classes in the JDK. I am referring to Panel.
The below code simply resolves your problem, i.e. displaying both the image and the button together – while using FlowLayout for the [content pane of the] JFrame. Notice that the preferred size of SignupButtonLayer is slightly larger than the size arguments in method setBounds.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
public class Panel extends JFrame {
private ImageIcon FirstPageImage;
private JLabel FirstPageLabel;
private JLayeredPane SignupButtonLayer;
private JButton Button;
public Panel() {
setLayout(new FlowLayout());
FirstPageImage = new ImageIcon(getClass().getResource("FirstPageAnimationUsing.gif"));
FirstPageLabel = new JLabel(FirstPageImage);
FirstPageImage.setImage(FirstPageImage.getImage().getScaledInstance(343, 820, Image.SCALE_DEFAULT));
add(FirstPageLabel);
Button = new JButton();
SignupButtonLayer = new JLayeredPane();
SignupButtonLayer.setPreferredSize(new Dimension(160, 90));
// Button.setOpaque(true);
Button.setBackground(Color.cyan);
Button.setBounds(0, 0, 159, 82);
SignupButtonLayer.add(Button, JLayeredPane.DEFAULT_LAYER);
add(SignupButtonLayer);
}
public static void main(String[] args) {
Panel gui = new Panel();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.pack();
gui.setTitle("Reminder App");
// gui.setSize(360, 850);
gui.setVisible(true);
}
}

How to Center JButtons in a centered JLabel in a BoxLayout?

I'm new in Java GUI programming and I have a strange issue with the BoxLayout:
I have an JLabel with an Icon. Added to the label are two JButtons. The Jlabel is placed in the CENTER position of the BorderLayout from a JFrame. Now I want that these two JButtons are always in the center of the JLabel even when I resize the JFrame. With setAlignmentX() the Jbuttons are centered horizontally , but there is no solution with setAlignmentY() for the vertical direction.
here is the code:
package footballQuestioner;
import java.awt.BorderLayout;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Houdini {
public static void main(String[] args) {
JFrame frame = new House();
}
}
class House extends JFrame {
private JLabel label = new JLabel(
new ImageIcon(
"C:\\Users\\laudatio\\Documents\\Java\\MyProject\\src\\footballQuestioner\\footballfield.jpg")
);
private JButton one=new JButton("one");
private JButton two=new JButton("two");
public House() {
label.setLayout(new BoxLayout(label, BoxLayout.Y_AXIS));
label.add(one);
label.add(two);
one.setAlignmentX(CENTER_ALIGNMENT);
one.setAlignmentY(CENTER_ALIGNMENT);
two.setAlignmentX(CENTER_ALIGNMENT);
two.setAlignmentY(CENTER_ALIGNMENT);
setLayout(new BorderLayout());
setLocation(300, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(true);
add(label,BorderLayout.CENTER);
pack();
setVisible(true);
}
}
Please Help! :-((((
but there is no solution with setAlignmentY() for the vertical direction.
Use "glue" before and after your two components. See the section from the Swing tutorial on How to Use Box Layout for more information and examples.
Although MadProgrammers comment to use a GridBagLayout is an easier solution, but knowing about "glue" and "struts" can be helpful for customizing the layout of a BoxLayout.

JTextField is blanking out my JPanels

I am attempting to learn more about creating more dynamic GUI's. I am hoping to add different panels with different content and as you press buttons on one main panel, it changes the adjacent panels. I have added two panels and some buttons and when I test the program, it displays correctly. The problem is when I add a JTextField (or JTextArea) the panels are blank and there are no buttons. The strange thing is I haven't added the JTextField to either panel. I have only created a global variable. If I comment it out, the program runs correctly. Am I missing something very simple?
Here is the gameWindow class that has the JTextField
package rpgcreator;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
class gameWindow extends JPanel {
JPanel startWindowPanel;
JPanel settingsPanel;
JPanel characterPanel;
JPanel scenarioPanel;
JPanel mapPanel;
JButton CharacterButton = new JButton("Create your character");
JButton StoryButton = new JButton("Choose your Story line");
JButton MapButton = new JButton("Choose your World");
//JTextField nameField = new JTextField(15); //comment or uncomment to see issue
public gameWindow() {
setLayout(new GridLayout(0,2,5,0));
startWindowPanel = new JPanel(new FlowLayout());
settingsPanel = new JPanel(new GridLayout(2,1));
startWindowPanel.setBackground(Color.blue);
settingsPanel.setBackground(Color.black);
startWindowPanel.add(MapButton);
startWindowPanel.add(StoryButton);
startWindowPanel.add(CharacterButton);
add(startWindowPanel);
add(settingsPanel);
}
}
Here is main
package rpgcreator;
import javax.swing.JFrame;
public class RPGCreator extends JFrame{
private static void mainWindow(){
RPGCreator mainwindow = new RPGCreator();
mainwindow.setSize(1200, 800);
mainwindow.setResizable(false);
mainwindow.setLocationRelativeTo(null);
mainwindow.setTitle("RPG Creator");
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
mainwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
// TODO code application logic here
mainWindow();
}
}
setVisible should go at the end. You're currently setting visible to true, and then adding a panel.
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
Put setVisible at the end after setDeaultCLoseOperation
I'm not entirely sure why it does it, maybe someone else can explain.
What I do know, is I usually call pack() which seems to make your problem go away.
private static void mainWindow(){
final RPGCreator mainwindow = new RPGCreator();
mainwindow.setMinimumSize(new Dimension(1200, 800));
mainwindow.setResizable(false);
mainwindow.setTitle("RPG Creator");
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
mainwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainwindow.pack(); //This usually goes after you've added all of your components
mainwindow.setLocationRelativeTo(null);
}
Some notes:
I had to change to mainwindow.setMinimumSize(new Dimension(1200, 800)); to avoid the frame looking squashed. Although I would usually let the layout manager deal with the sizes of things.
Call setLocationRelativeTo(null) after you call pack() so that it has the desired effect. Again not sure why, but I've learnt that through some hardship.

Wrapping JPanel around JCheckBox without any space - Swing

I want to display a vertical list of JCheckBox-es in a JPanel. But I have decided to wrap each JCheckBox with a JPanel, (thinking that i would need it in future). and i am going to stack these JPanels(containing one JCheckBox each) vertically in another JPanel using BoxLayout.
The BoxLayout is working as expected without any vertical space in between the JPanels added to them. My problem is with these inner JPanels containing individual checkbox. there is a considerable amount of space around the checkbox for each panel. I want to wrap these checkboxes tightly, so that the size of jcheckbox and that of the corresponding jpanel containing them are equal.
for these individual jpanel i have tried layouts - flowlayout and default layout. both didnt help.
How can i fix this? i just simply set the flowlayout and add the jcheckbox directly to the jpanel. no other code i have used.
I am adding an example code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class TryBox implements Runnable{
/**
* #param args
*/
public static void main(String args[])
{
SwingUtilities.invokeLater(new TryBox());
}
public void run()
{
class InnerPanel extends JPanel
{
public InnerPanel(int i) {
// TODO Auto-generated constructor stub
setLayout(new FlowLayout());
setBackground(new Color(i*50, i*50, i*50));
add(new JCheckBox("CheckBox "+i));
}
}
JPanel outerPanel = new JPanel();
outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.Y_AXIS));
for(int i=0;i<5;i++)
{
outerPanel.add(new InnerPanel(i));
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane sp = new JScrollPane(outerPanel);
frame.setPreferredSize(new Dimension(200, 600));
frame.getContentPane().add(new JScrollPane(outerPanel));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
here frame.setPreferredSize(new Dimension(200, 600)); is making the difference. i want the jpanels to reduce to the size of jcheckboxes. i dont want the jcheckboxes to fit into jpanel's size. if any extra vertical space is there in the container i want it to be left free.
The default layout of JPanel is FlowLayout, and the default constructor creates "a default 5-unit horizontal and vertical gap." You can specify no gap:
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
In addition, the JCheckBox UI delegate adds Insets that vary by L&F. I would be wary of changing these: the size is negligible and typically required to accommodate selection indication.
Did you try setting the margin and border insets to 0 (on the Swing components)?

Custom JComponent only Displays on JFrame not JPanel

Can somebody please help me understand why my custom JComponent 'Bar', only displays when added directly to the JFrame, and not when added to a JPanel (which is then added to the JFrame)?
Thanks!
package main;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Board {
public void start(){
JFrame frame = new JFrame();
JButton button1 = new JButton("Button 1");
Bar statusbar = new Bar();
JLabel status = new JLabel("Status: ");
JPanel topPanel = new JPanel();
topPanel.add(status);
topPanel.add(statusbar);
JPanel mainPanel = new JPanel();
mainPanel.add(button1);
mainPanel.add(statusbar);
frame.getContentPane().add(BorderLayout.NORTH, topPanel);
frame.getContentPane().add(BorderLayout.SOUTH, mainPanel);
frame.getContentPane().add(BorderLayout.CENTER, statusbar);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200,100);
frame.setVisible(true);
}
}
Here is my Bar Class...
package main;
import java.awt.Graphics;
import javax.swing.JComponent;
public class Bar extends JComponent{
public void paint(Graphics g){
g.fillRect(0, 0, 100, 10);
}
}
You're adding statusbar to several different places in the component tree, Swing doesn't deal with that well (or at all).
Create a separate Bar instances each time you use it, if you want their display to be synchronized, they should share the same model.
Edit
Ah, on a second glance, the problem here is that you never set a size (or preferred size) for the Bar components, so they get squished to 0 by the layout manager.
Try:
public static class Bar extends JComponent {
private Bar() {
setPreferredSize(new Dimension(25, 5));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(0, 0, 100, 10);
}
}
You should also add a frame.pack() before display.
(the multiple references to the same component thing is still true, too)
The dimension of the custom component is (0, 0).
When added to a container with a BorderLayout layout manager, it will expand to fill the available space, and therefore become visible.
When added to a container with a FlowLayout layout manager, it will not expand and will instead remain at its preferred size (i.e. (0, 0)). And therefore, will not become visible, albeit it is still there.
This explains why the custom component is only displayed when added directly to the JFrame, since it uses a BorderLayout layout manager, whereas a JPanel uses a FlowLayout layout manager.

Categories