i have a jpanel (jpanel A) with a button and when pressed
will open a tab jpanel (example 1)
so when you press the button you end up with 2 tabs jpanel A and example 1.
the original japanel is now a tabbed panel
when i delete example 1 i am left with jpanel A however this panel is in a tab
.
is there a way that i can revert back to the original jpanel when the other jpanel (example 1) is deleted.
i have made a sample application similar to mine:
after clicking on call a jpanel you get.
Then click press for tab 2 times you get 2 new tabs
after removing the 2 tabs you get:
WHAT I AM TRYING TO DO IS END UP WITH THIS:
i.e. BACK TO THE ORIGINAL REMOVE THE TAB KEEP THE CONTENT
THE APPLICATION IS SPLIT INTO 3 CLASSES.
CreatePanel to make the right hand side jpanel and hold the button to make tab.
MainGUI to create the jframe left side to call a panel on the right side.
CloseButtonTabbedPane to create the tab and control them.
here is the code:
MainGUI
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
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.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class MainGUI extends JFrame {
private JPanel jPanelLeft;
private JPanel jPanelRight;
private JButton callPanelBtn;
private JTabbedPane tab;
public MainGUI() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(1280, 600); // set frame size
this.setVisible(true); // display frame
this.setTitle("Tab Example");
setLayout(new BorderLayout()); // layout manager
jPanelLeft = new JPanel();
jPanelLeft.setLayout(null);
jPanelLeft.setPreferredSize(new Dimension(400, 800)); // to set the size of the left panel
jPanelLeft.setBackground(Color.blue);
this.add(jPanelLeft, BorderLayout.WEST);
callPanelBtn = new JButton("Call a jPanel");
callPanelBtn.addActionListener(btn);
callPanelBtn.setBounds(150, 200, 150, 40);
jPanelLeft.add(callPanelBtn);
jPanelRight = new JPanel();
jPanelRight.setBorder(new EmptyBorder(0, 0, 0, 0));
jPanelRight.setLayout(new GridLayout(0, 1));
this.add(jPanelRight);
tab = new CloseButtonTabbedPane();
}//endd constructor
ActionListener btn = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand() == "Call a jPanel") {
jPanelRight.add(new CreatePanel(t));
jPanelRight.revalidate();
}
}
};
// Actionlistener for CreatePanel
ActionListener t = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (tab.getTabCount() <= 8) {
// if no tabs make main tab
if (tab.getTabCount() == 0) {
tab.addTab("Main Content", jPanelRight); // name for listener not to close
add(tab);
revalidate();
repaint();
}
if (tab.getTabCount() > 0) {
JPanel newJPanel = new JPanel();
tab.addTab("new ", newJPanel);
tab.setSelectedIndex(tab.getTabCount() - 1);
}
}
}
};
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainGUI();
}
});
} // end main
}//end class
CreatePanel
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
public class CreatePanel extends JPanel {
private JPanel jPanel1;
private final JButton tabBTN;
public CreatePanel(ActionListener t){
jPanel1 = new JPanel();
jPanel1.setLayout(null);
jPanel1.setBorder(BorderFactory.createBevelBorder(1, Color.lightGray, Color.lightGray));
jPanel1.setPreferredSize(new Dimension(850, 300));
jPanel1.setBackground(Color.green);
add(jPanel1);
//add button for tabs
tabBTN = new JButton("Press for Tab");
tabBTN.setBounds(400, 100, 150, 30);
tabBTN.addActionListener(t);
jPanel1.add(tabBTN);
}//end constructor
}//end class
CloseButtonTabbedPane
import javax.swing.*;
import javax.swing.plaf.metal.MetalIconFactory;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CloseButtonTabbedPane extends JTabbedPane {
public CloseButtonTabbedPane() {
}
#Override
public void addTab(String title, Icon icon, Component component, String tip) {
super.addTab(title, icon, component, tip);
int count = this.getTabCount() - 1;
setTabComponentAt(count, new CloseButtonTab(component, title, icon));
}
#Override
public void addTab(String title, Icon icon, Component component) {
addTab(title, icon, component, null);
}
#Override
public void addTab(String title, Component component) {
addTab(title, null, component);
}
public class CloseButtonTab extends JPanel {
private Component tab;
public CloseButtonTab(final Component tab, String title, Icon icon) {
this.tab = tab;
setOpaque(false);
FlowLayout flowLayout = new FlowLayout(FlowLayout.CENTER, 3, 3);
setLayout(flowLayout);
setVisible(true);
JLabel jLabel = new JLabel(title);
jLabel.setIcon(icon);
add(jLabel);
JButton button = new JButton(MetalIconFactory.getInternalFrameCloseIcon(16));
button.setMargin(new Insets(0, 0, 0, 0));
button.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
button.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
JTabbedPane tabbedPane = (JTabbedPane) getParent().getParent();
if (tabbedPane.getSelectedIndex() >= 1) {
tabbedPane.remove(tab);
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
JButton button = (JButton) e.getSource();
button.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
}
public void mouseExited(MouseEvent e) {
JButton button = (JButton) e.getSource();
button.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
}
});
add(button);
}
}
}
I don't know if there is factory solution but for all JComponents you can set a custom UI Object that handles the Look & Feel means the appearance using the setUI method. One implementation for JTabbedPanes is called BasicTabbedPaneUI and has a method calculateTabAreaHeight that should calulate the height of the Tab Bar on Top.
So you could set your own instance of BasicTabbedPaneUI to your JTabbedPane overriding this method to return 0 if only one tab exists.
Put this in your constructor
[...]
tab = new CloseButtonTabbedPane();
tab.setUI(new BasicTabbedPaneUI(){
#Override
protected int calculateTabAreaHeight(int tabPlacement, int horizRunCount, int maxTabHeight){
if (tab.getTabCount() == 1) return 0;
return super.calculateTabAreaHeight(tabPlacement, horizRunCount, maxTabHeight);
}
});
Related
I started programming Java. This is my first window application. I did a simple tic-tac-toe game and I want the "o" button font color to be a different color. But it doesn't work. I can change the background color, but not the fonts, why?
package moje;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JTextField;
public class Kolko_i_krzyzyk extends JFrame implements ActionListener {
static JTextField tekst;
static JLayeredPane ekran = new JLayeredPane();
static JButton button = new JButton();
static int licznik=0;
public Kolko_i_krzyzyk () {
super("Kółko i krzyżyk");
ekran = new JLayeredPane();
setVisible(true);
setSize(800, 800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
//Siatka podzielona 3 na 3
setLayout(new GridLayout(3,3));
//Tworzenie 9 przycisków
for(int i = 1; i<=9; i++) {
JButton button = new JButton();
add(button);
button.addActionListener(this);
}
}
public static void main(String[] args) {
JFrame okno = new Kolko_i_krzyzyk();
}
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
if(licznik%2==0 ) {
button.setText("x");
button.setFont(new Font ("Arial", Font.BOLD, 90));
}
else {
button.setText("O");
button.setForeground(Color.RED);
button.setFont(new Font ("Arial", Font.BOLD, 90));
}
button.setEnabled(false);
licznik++;
}
}
The issue here is the default behavior when disabling the JButton via setEnabled(false).
This will grey out the button and ignore any color formatting you did to the text (foreground).
There are several workarounds to modify this behavior (as seen in this similar question).
Here is a short demonstration (without the final game logic of course) , which changes the UI of the JButton via setUI().
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.plaf.metal.MetalButtonUI;
public class Test {
private int counter = 0;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Test().buildGui());
}
private void buildGui() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
panel.setLayout(new GridLayout(3, 3));
for (int i = 1; i <= 9; i++) {
JButton button = new JButton() {
#Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
};
button.setFont(new Font("Arial", Font.BOLD, 90));
panel.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (counter % 2 == 0) {
button.setText("X");
button.setUI(new MetalButtonUI() {
// override the disabled text color for the button UI
protected Color getDisabledTextColor() {
return Color.BLUE;
}
});
} else {
button.setText("O");
button.setUI(new MetalButtonUI() {
protected Color getDisabledTextColor() {
return Color.RED;
}
});
}
button.setEnabled(false);
counter++;
}
});
}
frame.pack();
frame.setVisible(true);
}
}
Result:
Another (simpler) way to do it would be to build some ImageIcons for "X" and "O", then set these on the buttons via setIcon()/setDisabledIcon(). This would save you the trouble from modifying the button UI.
The idea is to have one "global" JFrame which I can then add/remove JPanels as needed to make a smooth flowing application. Currently, when I try changing from the first JPanel to the second, the second won't display. My code is below:
Handler (class to run the app):
package com.example.Startup;
import com.example.Global.Global_Frame;
public class Handler
{
public Handler()
{
gf = new Global_Frame();
gf.getAccNum();
gf.setVisible(true);
}
public static void main(String[] args)
{
new Handler();
}
Global_Frame gf = null;
}
public static void main(String[] args)
{
new Handler();
}
Global_Vars gv = null;
Global_Frame gf = null;
}
Global Frame:
package com.example.Global;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import com.example.FirstRun.AccDetails;
import com.example.FirstRun.FirstTimeRun;
public class Global_Frame extends JFrame
{
private static final long serialVersionUID = 1L;
ActionListener val = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
getUserDetails();
}
};
public Global_Frame()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // get look and feel based on OS
}
catch (ClassNotFoundException ex) // catch all errors that may occur
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (InstantiationException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (UnsupportedLookAndFeelException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
EventQueue.invokeLater(new Runnable()
{
public void run() //run the class's constructor, therefore starting the UI being built
{
initComponents();
}
});
}
public void initComponents()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
revalidate(); // revalidate the elements that will be displayed
repaint(); // repainting what is displayed if going coming from a different form
pack(); // packaging everything up to use
setLocationRelativeTo(null); // setting form position central
}
public void getAccNum()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
FirstTimeRun panel1 = new FirstTimeRun(val);
add(panel1);
revalidate();
repaint();
pack();
}
public void getUserDetails()
{
getContentPane().removeAll();
resizing(750, 500);
AccDetails panel2 = new AccDetails();
add(panel2);
revalidate();
repaint();
pack();
}
private void resizing(int width, int height)
{
timer = new Timer (10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0)
{
getContentPane().removeAll();
setPreferredSize(new Dimension(sizeW, sizeH));
revalidate();
repaint();
pack();
if (!wToggle)
sizeW += 2;
if (!hToggle)
sizeH += 2;
if (toggle)
{
setLocationRelativeTo(null);
toggle = false;
}
else
toggle = true;
if (sizeW == width)
wToggle = true;
if (sizeH == height)
hToggle = true;
if (hToggle && wToggle)
timer.stop();
}
});
timer.start();
}
//variables used for window resizing
private Timer timer;
private int sizeW = 600;
private int sizeH = 400;
private boolean toggle = false;
private boolean wToggle = false;
private boolean hToggle = false;
public int accNum = 0;
}
First Panel:
package com.example.FirstRun;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class FirstTimeRun extends JPanel
{
private static final long serialVersionUID = 1L;
public FirstTimeRun()
{
}
public FirstTimeRun(ActionListener val)
{
initComponents(val);
}
private void initComponents(ActionListener val) // method to build initial view for user for installation
{
pnlStart = new JPanel[1];
btnNext = new JButton();
pnlStart[0] = new JPanel();
btnNext.setText("Next"); // adding text to button for starting
btnNext.setPreferredSize(new Dimension(80, 35)); //positioning start button
btnNext.addActionListener(val);
pnlStart[0].add(btnNext); // adding button to JFrame
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlStart[0]);
}
// objects used in UI
private JPanel[] pnlStart;
private JButton btnNext;
}
Second Panel:
package com.example.FirstRun;
import java.awt.BorderLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AccDetails extends JPanel
{
private static final long serialVersionUID = 1L;
public AccDetails()
{
accAssets();
}
private void accAssets()
{
// instantiating elements of the GUI
pnlAccDetails = new JPanel[2];
lblWelcome = new JLabel();
lblMain = new JLabel();
for (int i = 0; i < 2; i++)
pnlAccDetails[i] = new JPanel();
lblWelcome.setText("Welcome to Example_App"); // label welcoming user
pnlAccDetails[0].setLayout(new BoxLayout(pnlAccDetails[0], BoxLayout.LINE_AXIS));
pnlAccDetails[0].add(lblWelcome); // adding label to form
lblMain.setText("<html>The following information that is collected will be used as part of the Example_App process to ensure that each user has unique Example_App paths. Please fill in all areas of the following tabs:</html>"); // main label that explains what happens, html used for formatting
pnlAccDetails[1].setLayout(new BorderLayout());
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_START);
pnlAccDetails[1].add(lblMain, BorderLayout.CENTER); //adding label to JFrame
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_END);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlAccDetails[0]);
add(pnlAccDetails[1]);
}
private JLabel lblWelcome;
private JLabel lblMain;
private JPanel[] pnlAccDetails;
}
I have tried using both a CardLayout and the "revalidate();" "repaint();" and "pack();" options and I'm stumped as to why it's not showing. Thanks in advance for any help that can be offered.
EDIT:
While cutting down my code, if the "resizing" method is removed, the objects are shown when the panels change. I would like to avoid having to remove this completely as it's a smooth transition for changing the JFrame size.
#John smith it is basic example of switch from one panel to other panel I hope this will help you to sort out your problem
Code:
package stack;
import java.awt.BorderLayout;
import java.awt.Dimension;
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;
public class RemoveAndAddPanel implements ActionListener{
JFrame frame;
JPanel firstPanel;
JPanel secondPanel;
JPanel controlPanel;
JButton nextButton;
public RemoveAndAddPanel() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firstPanel = new JPanel();
firstPanel.add(new JLabel("FirstPanel"));
firstPanel.setPreferredSize(new Dimension(100,100));
secondPanel = new JPanel();
secondPanel.add(new JLabel("Second panel"));
secondPanel.setPreferredSize(new Dimension(100,100));
nextButton = new JButton("Next panel");
controlPanel = new JPanel();
nextButton.addActionListener(this);
controlPanel.add(nextButton);
frame.setLayout(new BorderLayout());
frame.add(firstPanel,BorderLayout.CENTER);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.setVisible(true);
frame.setSize(300,100);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == nextButton) {
frame.remove(firstPanel);
frame.add(secondPanel);
nextButton.setEnabled(false);
}
frame.validate();
}
public static void main(String args[]) {
new RemoveAndAddPanel();
}
}
As mentioned in the edit, the problem lay within the resizing method. When the timer stopped, it wouldn't go anywhere, causing the UI to not load. The fix to the code is clearing the screen and adding the call to resizing to the actionlistener. Then adding a call to the next method after:
timer.stop();
Thanks for getting me to remove the mess around it and find the source of the problem #matt & #Hovercraft Full of Eels upvotes for both of you.
The main thing to consider while changing panel in a jframe is the layout, for a body(main) panel to change to any other panel the parent panel must be of type CardLayout body.setLayout(new java.awt.CardLayout());
After that you can now easily switch between panels wiht the sample code below
private void updateViewLayout(final HomeUI UI, final JPanel paneeelee){
final JPanel body = UI.getBody(); //this is the JFrame body panel and must be of type cardLayout
System.out.println("Page Loader Changing View");
new SwingWorker<Object, Object>() {
#Override
protected Object doInBackground() throws Exception {
body.removeAll();//remove all visible panel before
body.add(paneeelee);
body.revalidate();
body.repaint();
return null;
}
#Override
protected void done() {
UI.getLoader().setVisible(false);
}
}.execute();
}
I have a short toolbar at the left side of my application. When user points this toolbar, I open a semitransparent full toolbar (I use GlassPane to do it). All except semitransparency works fine.
Here is the screenshot of my example program:
As you see the first button is painted correctly, but all another have completly transparent background.
Here is my code (SSCCE):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.plaf.metal.MetalLookAndFeel;
/**
* <code>FlyOutExample</code>.
*/
public class FlyOutExample implements Runnable {
private static final String[] BUTTONS = {"First button", "Second", "Another button", "Last Button", "End"};
private static final Color HT_BLUE = new Color(0, 0, 255, 160); // half transparent blue
private JPanel shortPanel = new JPanel(new GridLayout(5, 1));
private JPanel fullPanel = new JPanel(new GridLayout(5, 1));
private JPanel fullPanelWrapper = new JPanel(new BorderLayout());
private JPanel shortPanelWrapper = new JPanel(new BorderLayout());
private JFrame frm;
public static void main(String[] args) {
SwingUtilities.invokeLater(new FlyOutExample());
}
#Override
public void run() {
try {
UIManager.setLookAndFeel(MetalLookAndFeel.class.getName());
} catch (Exception e) {
e.printStackTrace();
}
for (String s : BUTTONS) {
JButton b = new JButton(s.substring(0, 1));
b.setBackground(Color.BLUE);
b.setForeground(Color.RED);
b.setUI(new BasicButtonUI());
shortPanel.add(b);
b = new JButton(s);
b.setForeground(Color.RED);
b.setOpaque(false);
b.setHorizontalAlignment(SwingConstants.LEADING);
b.setBackground(HT_BLUE);
b.setUI(new BasicButtonUI() {
#Override
public void update(Graphics g, JComponent c) {
Color old = g.getColor();
g.setColor(HT_BLUE);
g.fillRect(0, 0, c.getWidth(), c.getHeight());
g.setColor(old);
paint(g, c);
}
});
fullPanel.add(b);
}
frm = new JFrame("Flyout example");
shortPanelWrapper.setOpaque(false);
shortPanelWrapper.add(shortPanel, BorderLayout.NORTH);
JPanel bluePanel1 = new JPanel();
bluePanel1.setOpaque(true);
bluePanel1.setBackground(Color.BLUE);
shortPanelWrapper.add(bluePanel1);
fullPanel.setOpaque(false);
fullPanelWrapper.setOpaque(false);
fullPanelWrapper.add(fullPanel, BorderLayout.NORTH);
JPanel bluePanel2 = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
Color old = g.getColor();
g.setColor(HT_BLUE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(old);
}
};
bluePanel2.setOpaque(false);
fullPanelWrapper.add(bluePanel2);
MouseListener openListener = new OpenSideBarListener();
for (Component c : shortPanel.getComponents()) {
c.addMouseListener(openListener);
}
bluePanel1.addMouseListener(openListener);
MouseListener closeListener = new CloseSideBarListener();
for (Component c : fullPanel.getComponents()) {
c.addMouseListener(closeListener);
}
bluePanel2.addMouseListener(closeListener);
JPanel topPanel = new JPanel();
topPanel.setBackground(Color.GREEN);
topPanel.setPreferredSize(new Dimension(0, 30));
JPanel bottomPanel = new JPanel();
bottomPanel.setBackground(Color.GREEN);
bottomPanel.setPreferredSize(new Dimension(0, 30));
frm.add(topPanel, BorderLayout.NORTH);
frm.add(bottomPanel, BorderLayout.SOUTH);
frm.add(shortPanelWrapper, BorderLayout.WEST);
frm.add(new JScrollPane(new JTable(40, 7)));
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private void openPopup() {
if (shortPanelWrapper.getMousePosition() != null) {
Container glassPane = (Container) frm.getGlassPane();
glassPane.setLayout(null);
fullPanelWrapper.setLocation(shortPanelWrapper.getLocation());
fullPanelWrapper.setSize(140, shortPanelWrapper.getHeight());
glassPane.add(fullPanelWrapper);
glassPane.setVisible(true);
}
}
private void closePopup() {
if (fullPanelWrapper.getMousePosition() == null) {
Container glassPane = (Container) frm.getGlassPane();
glassPane.removeAll();
glassPane.setVisible(false);
}
}
private class OpenSideBarListener extends MouseAdapter {
#Override
public void mouseEntered(MouseEvent e) {
openPopup();
}
}
private class CloseSideBarListener extends MouseAdapter {
#Override
public void mouseExited(MouseEvent e) {
closePopup();
}
}
}
My JDK is: 1.8_91, OS: Windows 7
My question is: what should I do to paint all my buttons correct?
P.S. In real application I have a custom UI for all buttons present in the left toolbar, so please don't remove the UI for my buttons.
UPDATE
I've started the app again (without any changes) and got another bug
Here ist the new picture:
Probably it's a bug of my graphic card?
The idea is to have one "global" JFrame which I can then add/remove JPanels as needed to make a smooth flowing application. Currently, when I try changing from the first JPanel to the second, the second won't display. My code is below:
Handler (class to run the app):
package com.example.Startup;
import com.example.Global.Global_Frame;
public class Handler
{
public Handler()
{
gf = new Global_Frame();
gf.getAccNum();
gf.setVisible(true);
}
public static void main(String[] args)
{
new Handler();
}
Global_Frame gf = null;
}
public static void main(String[] args)
{
new Handler();
}
Global_Vars gv = null;
Global_Frame gf = null;
}
Global Frame:
package com.example.Global;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import com.example.FirstRun.AccDetails;
import com.example.FirstRun.FirstTimeRun;
public class Global_Frame extends JFrame
{
private static final long serialVersionUID = 1L;
ActionListener val = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
getUserDetails();
}
};
public Global_Frame()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // get look and feel based on OS
}
catch (ClassNotFoundException ex) // catch all errors that may occur
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (InstantiationException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (UnsupportedLookAndFeelException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
EventQueue.invokeLater(new Runnable()
{
public void run() //run the class's constructor, therefore starting the UI being built
{
initComponents();
}
});
}
public void initComponents()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
revalidate(); // revalidate the elements that will be displayed
repaint(); // repainting what is displayed if going coming from a different form
pack(); // packaging everything up to use
setLocationRelativeTo(null); // setting form position central
}
public void getAccNum()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
FirstTimeRun panel1 = new FirstTimeRun(val);
add(panel1);
revalidate();
repaint();
pack();
}
public void getUserDetails()
{
getContentPane().removeAll();
resizing(750, 500);
AccDetails panel2 = new AccDetails();
add(panel2);
revalidate();
repaint();
pack();
}
private void resizing(int width, int height)
{
timer = new Timer (10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0)
{
getContentPane().removeAll();
setPreferredSize(new Dimension(sizeW, sizeH));
revalidate();
repaint();
pack();
if (!wToggle)
sizeW += 2;
if (!hToggle)
sizeH += 2;
if (toggle)
{
setLocationRelativeTo(null);
toggle = false;
}
else
toggle = true;
if (sizeW == width)
wToggle = true;
if (sizeH == height)
hToggle = true;
if (hToggle && wToggle)
timer.stop();
}
});
timer.start();
}
//variables used for window resizing
private Timer timer;
private int sizeW = 600;
private int sizeH = 400;
private boolean toggle = false;
private boolean wToggle = false;
private boolean hToggle = false;
public int accNum = 0;
}
First Panel:
package com.example.FirstRun;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class FirstTimeRun extends JPanel
{
private static final long serialVersionUID = 1L;
public FirstTimeRun()
{
}
public FirstTimeRun(ActionListener val)
{
initComponents(val);
}
private void initComponents(ActionListener val) // method to build initial view for user for installation
{
pnlStart = new JPanel[1];
btnNext = new JButton();
pnlStart[0] = new JPanel();
btnNext.setText("Next"); // adding text to button for starting
btnNext.setPreferredSize(new Dimension(80, 35)); //positioning start button
btnNext.addActionListener(val);
pnlStart[0].add(btnNext); // adding button to JFrame
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlStart[0]);
}
// objects used in UI
private JPanel[] pnlStart;
private JButton btnNext;
}
Second Panel:
package com.example.FirstRun;
import java.awt.BorderLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AccDetails extends JPanel
{
private static final long serialVersionUID = 1L;
public AccDetails()
{
accAssets();
}
private void accAssets()
{
// instantiating elements of the GUI
pnlAccDetails = new JPanel[2];
lblWelcome = new JLabel();
lblMain = new JLabel();
for (int i = 0; i < 2; i++)
pnlAccDetails[i] = new JPanel();
lblWelcome.setText("Welcome to Example_App"); // label welcoming user
pnlAccDetails[0].setLayout(new BoxLayout(pnlAccDetails[0], BoxLayout.LINE_AXIS));
pnlAccDetails[0].add(lblWelcome); // adding label to form
lblMain.setText("<html>The following information that is collected will be used as part of the Example_App process to ensure that each user has unique Example_App paths. Please fill in all areas of the following tabs:</html>"); // main label that explains what happens, html used for formatting
pnlAccDetails[1].setLayout(new BorderLayout());
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_START);
pnlAccDetails[1].add(lblMain, BorderLayout.CENTER); //adding label to JFrame
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_END);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlAccDetails[0]);
add(pnlAccDetails[1]);
}
private JLabel lblWelcome;
private JLabel lblMain;
private JPanel[] pnlAccDetails;
}
I have tried using both a CardLayout and the "revalidate();" "repaint();" and "pack();" options and I'm stumped as to why it's not showing. Thanks in advance for any help that can be offered.
EDIT:
While cutting down my code, if the "resizing" method is removed, the objects are shown when the panels change. I would like to avoid having to remove this completely as it's a smooth transition for changing the JFrame size.
#John smith it is basic example of switch from one panel to other panel I hope this will help you to sort out your problem
Code:
package stack;
import java.awt.BorderLayout;
import java.awt.Dimension;
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;
public class RemoveAndAddPanel implements ActionListener{
JFrame frame;
JPanel firstPanel;
JPanel secondPanel;
JPanel controlPanel;
JButton nextButton;
public RemoveAndAddPanel() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firstPanel = new JPanel();
firstPanel.add(new JLabel("FirstPanel"));
firstPanel.setPreferredSize(new Dimension(100,100));
secondPanel = new JPanel();
secondPanel.add(new JLabel("Second panel"));
secondPanel.setPreferredSize(new Dimension(100,100));
nextButton = new JButton("Next panel");
controlPanel = new JPanel();
nextButton.addActionListener(this);
controlPanel.add(nextButton);
frame.setLayout(new BorderLayout());
frame.add(firstPanel,BorderLayout.CENTER);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.setVisible(true);
frame.setSize(300,100);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == nextButton) {
frame.remove(firstPanel);
frame.add(secondPanel);
nextButton.setEnabled(false);
}
frame.validate();
}
public static void main(String args[]) {
new RemoveAndAddPanel();
}
}
As mentioned in the edit, the problem lay within the resizing method. When the timer stopped, it wouldn't go anywhere, causing the UI to not load. The fix to the code is clearing the screen and adding the call to resizing to the actionlistener. Then adding a call to the next method after:
timer.stop();
Thanks for getting me to remove the mess around it and find the source of the problem #matt & #Hovercraft Full of Eels upvotes for both of you.
The main thing to consider while changing panel in a jframe is the layout, for a body(main) panel to change to any other panel the parent panel must be of type CardLayout body.setLayout(new java.awt.CardLayout());
After that you can now easily switch between panels wiht the sample code below
private void updateViewLayout(final HomeUI UI, final JPanel paneeelee){
final JPanel body = UI.getBody(); //this is the JFrame body panel and must be of type cardLayout
System.out.println("Page Loader Changing View");
new SwingWorker<Object, Object>() {
#Override
protected Object doInBackground() throws Exception {
body.removeAll();//remove all visible panel before
body.add(paneeelee);
body.revalidate();
body.repaint();
return null;
}
#Override
protected void done() {
UI.getLoader().setVisible(false);
}
}.execute();
}
I have been trying to add a pop up menu to the tab title of a JTabbedPane, which I have managed to do as follows:
tabbedPane.setTabComponentAt(a+2, x);
x.addMouseListener(new MouseListener() {
#Override
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
#Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseClicked(MouseEvent e) {}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
popUpMenuTab.show(e.getComponent(),
e.getX(), e.getY());
}
}
});
However, with this if you right click you get the context menu, but if you left click nothing happnes. Does anyone know how I can get the orginal functionality back on the tab so that it changes to being active on a left click but also has the context menu on a right click.
An SSCCE is as follows
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
public class JTabbedPaneDemoextends JPanel {
private JPopupMenu menu = new JPopupMenu();
public JTabbedPaneDemo() {
ImageIcon icon = new ImageIcon("java-swing-tutorial.JPG");
JTabbedPane jtbExample = new JTabbedPane();
JPanel jplInnerPanel1 = createInnerPanel("Tab 1 Contains Tooltip and Icon");
jtbExample.addTab("One", icon, jplInnerPanel1, "Tab 1");
jtbExample.setSelectedIndex(0);
JPanel jplInnerPanel2 = createInnerPanel("Tab 2 Contains Icon only");
jtbExample.addTab("Two", icon, jplInnerPanel2);
JPanel jplInnerPanel3 = createInnerPanel("Tab 3 Contains Tooltip and Icon");
jtbExample.addTab("Three", icon, jplInnerPanel3, "Tab 3");
JPanel jplInnerPanel4 = createInnerPanel("Tab 4 Contains Text only");
jtbExample.addTab("Four", jplInnerPanel4);
menu.add(new JMenuItem("Item 1"));
menu.add(new JMenuItem("Item 2"));
JLabel tab4Label = new JLabel();
tab4Label.setText("Four");
jtbExample.setTabComponentAt(3, tab4Label);
tab4Label.addMouseListener(new MouseListener() {
#Override
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
#Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseClicked(MouseEvent e) {}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
menu.show(e.getComponent(),
e.getX(), e.getY());
}
}
});
//Add the tabbed pane to this panel.
setLayout(new GridLayout(1, 1));
add(jtbExample);
}
protected JPanel createInnerPanel(String text) {
JPanel jplPanel = new JPanel();
JLabel jlbDisplay = new JLabel(text);
jlbDisplay.setHorizontalAlignment(JLabel.CENTER);
jplPanel.setLayout(new GridLayout(1, 1));
jplPanel.add(jlbDisplay);
return jplPanel;
}
public static void main(String[] args) {
JFrame frame = new JFrame("TabbedPane Source Demo");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);}
});
frame.getContentPane().add(new JTabbedPaneDemo(),
BorderLayout.CENTER);
frame.setSize(400, 125);
frame.setVisible(true);
}
}
Here you can left click on tab 4 but you can't right click.
Update: Coincidentally, this answer uses the same approach as #Neifen's answer, but the example may be worth preserving.
Setting the tabbed pane model's selected index seems to work: getModel().setSelectedIndex(3). I've updated your example to use the event dispatch thread and to be an sscce by making it self-contained.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
/** #see https://stackoverflow.com/questions/7818752 */
public class JTabbedPaneDemo extends JPanel {
private JPopupMenu menu = new JPopupMenu();
public JTabbedPaneDemo() {
Icon icon = UIManager.getIcon("html.pendingImage");
final JTabbedPane jtb = new JTabbedPane();
JPanel jplInnerPanel1 = createInnerPanel("Tab 1: Tooltip and Icon");
jtb.addTab("One", icon, jplInnerPanel1, "Tab 1");
jtb.setSelectedIndex(0);
JPanel jplInnerPanel2 = createInnerPanel("Tab 2: Icon only");
jtb.addTab("Two", icon, jplInnerPanel2);
JPanel jplInnerPanel3 = createInnerPanel("Tab 3: Tooltip and Icon");
jtb.addTab("Three", icon, jplInnerPanel3, "Tab 3");
JPanel jplInnerPanel4 = createInnerPanel("Tab 4: Text only");
jtb.addTab("Four", jplInnerPanel4);
menu.add(new JMenuItem("Item 1"));
menu.add(new JMenuItem("Item 2"));
JLabel tab4Label = new JLabel();
tab4Label.setText("Four");
jtb.setTabComponentAt(3, tab4Label);
tab4Label.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
#Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
jtb.getModel().setSelectedIndex(3);
if (e.isPopupTrigger()) {
menu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
setLayout(new GridLayout());
add(jtb);
}
private JPanel createInnerPanel(String text) {
JPanel jplPanel = new JPanel();
JLabel jlbDisplay = new JLabel(text);
jlbDisplay.setHorizontalAlignment(JLabel.CENTER);
jplPanel.setLayout(new GridLayout(1, 1));
jplPanel.add(jlbDisplay);
return jplPanel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("TabbedPane Source Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTabbedPaneDemo());
frame.pack();
frame.setSize(400, 125);
frame.setVisible(true);
}
});
}
}
This is my Solution:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
public class JTabbedPaneDemo extends JPanel {
private JPopupMenu menu = new JPopupMenu();
private JTabbedPane jtbExample;
public JTabbedPaneDemo() {
ImageIcon icon = new ImageIcon("java-swing-tutorial.JPG");
jtbExample = new JTabbedPane();
JPanel jplInnerPanel1 = createInnerPanel("Tab 1 Contains Tooltip and Icon");
jtbExample.addTab("One", icon, jplInnerPanel1, "Tab 1");
jtbExample.setSelectedIndex(0);
JPanel jplInnerPanel2 = createInnerPanel("Tab 2 Contains Icon only");
jtbExample.addTab("Two", icon, jplInnerPanel2);
JPanel jplInnerPanel3 = createInnerPanel("Tab 3 Contains Tooltip and Icon");
jtbExample.addTab("Three", icon, jplInnerPanel3, "Tab 3");
JPanel jplInnerPanel4 = createInnerPanel("Tab 4 Contains Text only");
jtbExample.addTab("Four", jplInnerPanel4);
menu.add(new JMenuItem("Item 1"));
menu.add(new JMenuItem("Item 2"));
JLabel tab4Label = new JLabel();
tab4Label.setText("Four");
jtbExample.setTabComponentAt(3, tab4Label);
tab4Label.addMouseListener(new TabbedMouseListener(3));
// Add the tabbed pane to this panel.
setLayout(new GridLayout(1, 1));
add(jtbExample);
}
protected JPanel createInnerPanel(String text) {
JPanel jplPanel = new JPanel();
JLabel jlbDisplay = new JLabel(text);
jlbDisplay.setHorizontalAlignment(JLabel.CENTER);
jplPanel.setLayout(new GridLayout(1, 1));
jplPanel.add(jlbDisplay);
return jplPanel;
}
/**
*
* Mouselistener for the Tabbedpane
*
*/
class TabbedMouseListener extends MouseAdapter {
private final int index;
/**
* Constructor
*
* #param index
* the index of the tab
*/
public TabbedMouseListener(int index) {
this.index = index;
}
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
menu.show(e.getComponent(), e.getX(), e.getY());
}
else {
jtbExample.setSelectedIndex(index);
}
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("TabbedPane Source Demo");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.getContentPane().add(new JTabbedPaneDemo(), BorderLayout.CENTER);
frame.setSize(400, 125);
frame.setVisible(true);
}
}
I have made a the listener as a class. When you declare the listener you can put the index of the tab as parameter.
I also made the tabbedPane global