I have a class that reads an excelfile and creates frame with a graph inside a jpanel. I invoke this class through an actionlistener in a jmenuitem. Then I have another jmenuitem that invokes the same class that opens the same file, but reads a different excel sheet, and gives a different graph (thats the only string that changes in the class). The jmenubar that has these jmenitems belong to a jframe from which the program starts. I would like to know if it is possible every time I click the jmenuitems that create the graphs to be added in a new jframe cardlayout, so that I can roll on them. Thanks in advance
This is the code I am currently using to open a graph in a jframe when the jmenuitem is clicked:
public class startup extends JFrame { // creates a jframe with some stuff and the jmenubar
public void menu() {
...
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event2) {
new Thread(new Runnable() {
#Override
public void run() {
new ReadExcel();
ReadExcel.excel(".xls", 0); // this jmenuitem invokes the class to read the excelfile sheet 0
graphgen.main(null);
}
}).start();
}
});
subsubmenu1.add(menuItem);
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event2) {
new Thread(new Runnable() {
#Override
public void run() {
new ReadExcel();
ReadExcel.excel(".xls", 1); // this jmenuitem invokes the class to read the excelfile sheet 1
graphgen.main(null);
}
}).start();
}
});
subsubmenu1.add(menuItem);
....
}
public static void main(String[] args)
{
GUIquery frame = new GUIquery();
p.add(graphComponent, BorderLayout.CENTER);
frame.setLayout(new BorderLayout());
frame.add(p, BorderLayout.CENTER);
frame.setJMenuBar(GUIquery.createMenuBar());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.setSize(1600, 1200);
frame.setVisible(true);
}
}
The readexcel class just reads an excelsheet of an excelfile and returns some arraylist which are processed in the graphgen class.
public class graphgen extends JFrame {
public graphgen() {
super("Results");
gen();
}
public void gen(){
//creates the graphcomponent
getContentPane().add(graphComponent);
add(graphComponent);
}
public static void main(String[] args)
{
graphgen frame = new graphgen();
p2.add(graphComponent, BorderLayout.CENTER);
frame.add(p2, BorderLayout.CENTER);
frame.pack();
frame.setResizable(true);
frame.setSize(1600, 1200);
frame.setVisible(true);
}
Use Action to encapsulate the target component, file and sheet, as shown here and here. Add a method to update state of the class based on the chosen sheet. Examples of navigating among cards are seen here and here. See also Card Layout Actions, cited here.
Related
This has been asked before but I would like clarification, I'm new to java coding (sort of, started coding last month) and would like to know simply how can I switch between UIs in one JFrame, Picture this, a settings menu, How do I make it in one JFrame window instead of just make a new window with all the settings, If you don't get it, ask for clarification.
You can implement a frame (JFrame) and, for example, two panels (JPanel). Initially you embed panel A inside frame, when you want to show panel B then call the method showPanelB()
public class MyFrame extends JFrame {
PanelA panelA = new PanelA();
PanelB panelB = new PanelB();
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MyFrame().setVisible(true);
}
});
}
public MyFrame() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
showPanelA();
}
public void showPanelA() {
getContentPane().add(panelA, BorderLayout.CENTER);
}
public void showPanelB() {
getContentPane().add(panelB, BorderLayout.CENTER);
}
}
class PanelA extends JPanel {
// Panel implementation
}
class PanelB extends JPanel {
// Panel implementation
}
My class Output.java extends JPanel. From another class, the user can click on an icon and then it locally creates a JFrame with the Output.java. We found that sometimes the user minimizes that window and then will want it back. He will then reclick on the icon and the JFrame is recreated. By doing it a few times, the Output.java class is displayed several times.
I've found that it is possible to disable multiple JFrame creation by adding this:
if (!output.isShowing())
openPage(output);
But it doesn't restore the JFrame. Is there a way to restore a minimized JFrame in this situation?
icon.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
openPage(outputsSlavePane);
}
});
private void openPage(final Output panel) {
JFrame frame = new JFrame("Output");
frame.add(panel);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
panel.setLostFocus();
}
});
}
Thanks.
Don't keep creating new JFrames.
Instead create a field that references the JFrame, and restore the field, not a new JFrame.
Create a field to reference the JDialog. If the field is null, then locally create it and assign it to the field (this is called "lazy" creation). If the field isn't null, don't re-create it, just display it.
Having said this, most all Swing GUI applications should have only one JFrame, only one main application window. If sub-windows are needed, they should be JDialogs, not JFrames. Please check out The Use of Multiple JFrames, Good/Bad Practice?
An example of "lazy" creation:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class LazyCreation extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private Output output = new Output();
private JDialog outputDialog = null;
public LazyCreation() {
add(new JButton(new DisplayOutputAction("Display Output")));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class DisplayOutputAction extends AbstractAction {
public DisplayOutputAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
// lazily create dialog here
if (outputDialog == null) {
Window currentWin = SwingUtilities.getWindowAncestor(LazyCreation.this);
outputDialog = new JDialog(currentWin, "Output Dialog", ModalityType.MODELESS);
outputDialog.add(output);
outputDialog.pack();
outputDialog.setLocationRelativeTo(currentWin);
}
outputDialog.setVisible(true);
}
}
private static void createAndShowGui() {
LazyCreation mainPanel = new LazyCreation();
JFrame frame = new JFrame("LazyCreation");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Output extends JPanel {
private JLabel label = new JLabel("Output", SwingConstants.CENTER);
public Output() {
label.setFont(label.getFont().deriveFont(Font.BOLD, 36));
add(label);
}
}
You can restore a minimized frame by calling
frame.setState(JFrame.NORMAL);
The current state of the frame can be retrieved by
frame.getState() // NORMAL or ICONIFIED
I'm trying to use the DJ Native Swing API to open a WebBrowser on my code:
public class YoutubeViewer {
public static void main(String[] args) {
NativeInterface.open();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("YouTube Viewer");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(getBrowserPanel(null), BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
NativeInterface.runEventPump();
// don't forget to properly close native components
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
NativeInterface.close();
}
}));
}
public static JPanel getBrowserPanel(String trailer) {
trailer = "https://www.youtube.com/watch?feature=player_detailpage&v=6kw1UVovByw";
JPanel webBrowserPanel = new JPanel(new BorderLayout());
JWebBrowser webBrowser = new JWebBrowser();
webBrowserPanel.add(webBrowser, BorderLayout.CENTER);
webBrowser.setBarsVisible(false);
webBrowser.navigate(trailer);
return webBrowserPanel;
}
}
But I keep getting this error:
Could anyone help me?
This kind of exception is caused when the class loader (module of the interpreter) do not locate the respective class (SWTNativeInterface, in your case) in the class path. You should place the respective library in the project's classpath.
You set this classpath in the project properties.
I want to change the JPanel of a JFrame, using the CardLayout class.
I have already run this example and it works.
Now I want to use as action listener, the JMenuItem; so If I press that JMenuItem, I want to change it, with a specific panel. So this is the JFrame:
public class FantaFrame extends JFrame implements Observer {
private static final long serialVersionUID = 1L;
private JPanel cardPanel = new JPanel();
private CardLayout cardLayout = new CardLayout();
public FantaFrame(HashMap<String, JPanel> fantaPanels) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("FantaCalcio App");
setSize(500, 500);
cardPanel.setLayout(cardLayout);
setPanels(fantaPanels);
}
public void update(Observable o, Object arg) {
cardLayout.show(cardPanel, arg.toString());
}
private void setPanels(HashMap<String, JPanel> fantaPanels) {
for (String name : fantaPanels.keySet()) {
cardPanel.add(fantaPanels.get(name), name);
}
}
}
Those are the Menu, the Controller and the Main:
private void pressed(){
home.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
controller.changePanel(home.getText());
}
});
}
public class Controller extends Observable {
public void changePanel(String panel){
setChanged();
notifyObservers(panel);
}
}
public static void main(String[] args) {
fantaPanels.put("Login", new LoginPanel());
Controller controller = new Controller();
MenuBarApp menuApp = new MenuBarApp(controller);
FantaFrame frame = new FantaFrame(fantaPanels);
frame.setJMenuBar(menuApp);
controller.addObserver(frame);
frame.setVisible(true);
}
The problem is that the JPanel doesn't change. What do you think is the problem ?
I've already debugged it, and in the update() method, the correct String value arrives.
You never add the cardPanel JPanel, the one using the CardLayout and displaying the "cards" to anything. You need to add it to your JFrame's contentPane for it to display anything. i.e.,
public FantaFrame(HashMap<String, JPanel> fantaPanels) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("FantaCalcio App");
setSize(500, 500);
cardPanel.setLayout(cardLayout);
add(cardPanel, BorderLayout.CENTER); // ****** add this line ******
setPanels(fantaPanels);
}
I want to know how to show an internal frame in swing. That means,when a JFrame is needed, normally what I do is,
new MyJFrame().setVisible(true);
Let's say the previous form should be displayed as well. And when this new frame is displayed,another new icon is displayed on the task bar.(it sounds like two separate applications run in one application) I want to avoid showing that icon and display both frames as they are in one application. Thank you
..want to avoid showing that icon and display both frames as they are in one application.
Another solution is to put the 2nd and subsequent free floating elements in a JDialog.
E.G. of using both a frame and dialog to hold extra content.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class FrameTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
initGui();
}
});
}
public static void initGui() {
final JFrame f = new JFrame("Frame Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel gui = new JPanel(new GridLayout(0,1,5,5));
final Content c = new Content();
JButton frame = new JButton("Frame");
frame.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JFrame f2 = new JFrame("Content");
f2.add(c.getContent());
f2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f2.pack();
f2.setLocationByPlatform(true);
f2.setVisible(true);
}
});
gui.add(frame);
JButton dialog = new JButton("Dialog");
dialog.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JDialog d = new JDialog(f);
d.add(new Content().getContent());
d.pack();
d.setLocationByPlatform(true);
d.setVisible(true);
}
});
gui.add(dialog);
f.add(gui);
f.pack();
f.setVisible(true);
}
}
class Content {
public Component getContent() {
JPanel p = new JPanel();
p.add(new JLabel("Hello World!"));
return p;
}
}
You have one JFrame for an application.
You can display multiple JPanels within a JFrame.
Or, as trashgod pointed out, you can have multiple JInternalFrames within a JDesktopFrame.