Internal JFrames - java

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.

Related

JDesktopPane not displaying any component

I'm experimenting with desktop panes so I can use them in my work projects. The problem here is that I want to use an JInternalFrame within a JDesktopPane, in a normal JPanel it shows normally but cannot move it, using the desktop pane doesn't display any component added.
Here is the code of the last try, is simple just for learning how it works:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Internal_FrameShowtst extends JFrame{
Internal_FrameShowtst(){
BorderLayout bl = new BorderLayout();
JDesktopPane p = new JDesktopPane();
JPanel p1 = new JPanel();
JButton b = new JButton("click");
JInternalFrame in = new JInternalFrame("Test");
Internal_Frametst ift = new Internal_Frametst();
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//p1.add(new JLabel("hola"));
//in.add(p1);
//in.setVisible(true);
ift.setVisible(true);
}
});
p1.add(b);
bl.addLayoutComponent(p,BorderLayout.CENTER);
//p.add(in);
p.add(ift);
p.repaint();
setLayout(bl);
add(p);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Internal_FrameShowtst().setVisible(true);
}
});
}
}
custom internal frame class:
import javax.swing.*;
public class Internal_Frametst extends JInternalFrame {
Internal_Frametst(){
JPanel p = new JPanel();
JLabel label = new JLabel("Halo");
setIconifiable(true);
//setIcon(true);
setClosable(true);
p.add(label);
p.setSize(300,300);
add(p);
//setVisible(true);
}
}
I've read and tried the following:
Components inside JDesktopPane not showing
JDesktopPane not displaying components when adding JInternalFrame
I've tried adding the components directly, adding a JPanel, adding the internal frame, trying without it, creating the internal frame in the main class, creating my own internal frame in its own class, using layout managers with both panels (normal and desktop), all with the same result.
Your code creates several components that are never added to the visible UI at all. In the version you have posted, the internal frame is invisible and the button to make it visible is not part of the frame. But there are also problems with the initial sizes of the components.
I strongly recommend to keep the creation of a component, the setting of its initial properties, and the code to add it to a parent component close together in your source code.
Further, consider the points discussed in Prefer composition over inheritance? Your subclasses are entirely unnecessary.
Here is a revised version of your code that will open the internal frame when the button is clicked:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.*;
public class UiExample {
public static void main(String[] args) {
EventQueue.invokeLater(UiExample::initializeUI);
}
static void initializeUI() {
JPanel p1 = new JPanel();
JButton b = new JButton("Show Internal Frame");
p1.add(b);
JInternalFrame ift = initializeInternalFrame();
b.addActionListener(e -> {
ift.pack();
ift.setVisible(true);
});
JDesktopPane p = new JDesktopPane();
p.add(ift);
JFrame mainFrame = new JFrame();
mainFrame.setSize(300, 200);
mainFrame.getContentPane().add(p, BorderLayout.CENTER);
mainFrame.getContentPane().add(p1, BorderLayout.PAGE_START);
mainFrame.setVisible(true);
}
static JInternalFrame initializeInternalFrame() {
JInternalFrame iFrame = new JInternalFrame();
iFrame.setIconifiable(true);
// setIcon(true);
iFrame.setClosable(true);
iFrame.setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE);
JPanel p = new JPanel();
p.add(new JLabel("Hello"));
iFrame.add(p);
return iFrame;
}
}
Note that setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE) is necessary for being able to show the frame again via setVisible(true) after the internal frame has been closed.

OK button and String not showing up on JPanel

I am trying to make a panel showing a printed statement "Hello World!" and an OK button. Neither will show up on the panel and I have no idea why. I started with a block of code that was supposed to create just a blank popup. The blank popup worked great. I can't add the string or button and see them. I have tried calling paintComponent. I have tried adding the content to the panel. Does anyone know what I am missing?
Here is my code
package painting;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SwingPaintDemo1 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static class SwingPaintDemo extends JPanel{
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Hello World!", 20,30);
}
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(250,250);
f.setVisible(true);
JButton okbutton = new JButton("OK");
ButtonHandler listener = new ButtonHandler();
okbutton.addActionListener(listener);
SwingPaintDemo displayPanel = new SwingPaintDemo();
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
content.add(displayPanel, BorderLayout.CENTER);
content.add(okbutton, BorderLayout.SOUTH);
}
private static class ButtonHandler implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
}
You forgot to add the JPanel to the JFrame. Just add the following line at the bottom of your createAndShowGUI() method:
f.add(content);
I would also recommend moving your f.setVisible(true); line to the bottom of the method just to be safe. When you make the frame visible, the component tree is set up to take into account all the components added to the JFrame. If you add more components after that, you will need to do either manually revalidate the tree or do something that triggers an automatic revalidation. I'm assuming you're not revalidating your tree anywhere, so you should move f.setVisible(true); to after all the components are added.

ColorChooser by clicking JMenu Item

I tried codes from different site's and one from here about a color. How do I get color chooser to work with the press of a jmenu item?
I looked at ColorChooser Example and also Oracle Color Chooser Example and then implementing into the original class using the following code:
JMenuItem clr = new JMenuItem("Font Color");
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ColorChooserDemo ccd = new ColorChooserDemo();
ccd.setVisible(true);
}
});
But this seems do do nothing when I press the menu item.
The class code is from the oracle webpage. These are the following class I use (shortened of course to the problem at hand). I'm making a notepad program as i'm getting back into programming and refreshing my memory of how to do things in java. Problem at hand is, I am unable to get the color chooser to come up when I click on the jmenuitem clr (which is font color) the following code show's what I have so far:
Color Chooser Class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.colorchooser.*;
/* ColorChooserDemo.java requires no other files. */
#SuppressWarnings("serial")
public class ColorChooserDemo extends JPanel
implements ChangeListener {
protected JColorChooser tcc;
protected JLabel banner;
public ColorChooserDemo() {
super(new BorderLayout());
//Set up color chooser for setting text color
tcc = new JColorChooser();
tcc.getSelectionModel().addChangeListener(this);
tcc.setBorder(BorderFactory.createTitledBorder(
"Choose Text Color"));
add(tcc, BorderLayout.PAGE_END);
}
public void stateChanged(ChangeEvent e) {
Color newColor = tcc.getColor();
FirstWindow.ta1.setForeground(newColor);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("ColorChooserDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new ColorChooserDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Main Class:
import java.awt.EventQueue;
public class Main{
protected static Object fw;
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
try
{
FirstWindow fw = new FirstWindow();
fw.setVisible(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
});
}
}
FirstWindow class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class FirstWindow extends JFrame {
private static final long serialVersionUID = 1L;
protected JColorChooser tcc;
protected static JTextArea ta1;
public FirstWindow() {
super("Note Pad");
Font font = new Font("Verdana", Font.BOLD, 12);
//Setting the size of the note pad
setSize(650, 745);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//Create the MenuBar
JMenuBar mb = new JMenuBar();
setJMenuBar(mb);
//Create the panel to hold everything in
JPanel p = new JPanel();
//Create the Text Area
final JTextArea ta1 = new JTextArea();
ta1.setFont(font);
ta1.setMargin(new Insets(5,5,5,5));
ta1.setLineWrap(true);
ta1.setWrapStyleWord(true);
//Create the Scroll Pane to hold the Text Area
final JScrollPane sp = new JScrollPane(ta1);
sp.setPreferredSize(new Dimension(625,675));
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
//Create the menu's
JMenu format = new JMenu("Format");
//Create menu item for picking font color
JMenuItem clr = new JMenuItem("Font Color");
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ColorChooserDemo ccd = new ColorChooserDemo();
ccd.setVisible(true);
}
});
//adding the menu items to the file menu tab
//adding menu items to the edit tab
//adding menu items to the format tab
format.add(clr);
//adding the menus to the menu bar
mb.add(format);
//adding the scroll pane to the panel
p.add(sp);
add(p, BorderLayout.CENTER);
}
}
Probably the easiest way to show the ColorChooser is the following:
In the ColorChooserDemo class, you have the method private static void createAndShowGUI(), which you should declare public.
Then, replace the ActionListener for the menu item to the following:
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ColorChooserDemo.createAndShowGUI();
}
});
Your ColorChooserDemo class extends JPanel, not JFrame. You first need a JFrame, then add the panel, then show the JFrame. This is what happens in the createAndShowGUI() method.
Edit:
I understood that you only wanted to know how to show the ColorChooserDemo when selecting a menu item.
However, to actually set the color, you might want to skip using your own ColorChooserDemo class, and replace the ActionListener code with the following:
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
Color c = JColorChooser.showDialog(ta1, "ColorChooserDemo", null);
ta1.setForeground(c);
}
});
An SSCE is easier not only for us to provide a solution, as Andrew suggested, but it may also help you figure out and understand what to do. Anyway, here's a quick example of opening a colour chooser after pressing a JMenuItem:
item.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JColorChooser jColorChooser = new JColorChooser();
JDialog jDialog = new JDialog();
jDialog.setContentPane(jColorChooser);
jDialog.pack();
jDialog.setVisible(true);
}
});
LE: (sorry, new to colour choosers myself) or just use JColorChooser.showDialog()

Adding jpanels created from the same class to a cardlayout frame

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.

One JFrame opening another

I have a JFrame and JPanel full of Jsomethings with an actionlistener. When the user clicks an object I want to open another JFrame. Here is what I did:
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == rejectionbutton){
RejectApp ra = new RejectApp();
ra.main(null);
}
}
(RejectApp calls a new JFrame.) So another JFrame opens on the screen with more options. It works OK (so far), but I want to know is this standard? I mean calling the main method like this?
Another question is, without using a cardlayout (which I don't want to use), is the best way to handle multiple panels, by doing this sort of thing?
I would change a few things. First off, usually an application has one JFrame and then if it needs to show another window does so as a modal or non-modal dialog such as can be obtained with a JDialog or JOptionPane. Having said that, it's even more common to have one JFrame and swap "views" in the JFrame -- swap contentPanes or other large panels via a CardLayout as this would mimic the behavior of many gui programs we all currently use.
Personally, I also try to gear my GUI creation towards creating a JPanel or JComponent rather than towards creating a top-level window. This way if I want to display the GUI as a stand alone app, a dialog, or an applet I can pop it into the contentPane of a JFrame or JDialog or JApplet respectively, or if as an inner panel of a more complex GUI, then insert it there, or in an application with a swapping view, then as a card in a CardLayout as noted above. The bottom line is I feel that this structure gives you the developer a lot more options in how you can use this GUI.
Also, I would avoid calling another class's main as you're doing (assuming this is the public static void main method) as you lose all benefits of OOPs. You also seem to be trying to call a static method in a non-static way (assuming I understand your program structure correctly).
For your second question, it begs a question of my own: why do you not want to use CardLayout?
edit: an example of what I meant is as follows:
import java.awt.Dimension;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SwingEg {
private static void createAndShowUI() {
JFrame frame = new JFrame("Main JFrame");
frame.getContentPane().add(new MainGUI().getMainPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class MainGUI {
private static final Dimension MAIN_PANEL_SIZE = new Dimension(450, 300);
private JPanel mainPanel = new JPanel();
private JDialog modalDialog;
private JDialog nonModalDialog;
public MainGUI() {
JButton openModalDialogBtn = new JButton("Open Modal Dialog Window");
openModalDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openModalDialogBtnActionPerformed(e);
}
});
JButton openNonModalDialogBtn = new JButton("Open Non-Modal Dialog Window");
openNonModalDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openNonModalDialogBtnActionPerformed(e);
}
});
mainPanel.setPreferredSize(MAIN_PANEL_SIZE);
mainPanel.add(openModalDialogBtn);
mainPanel.add(openNonModalDialogBtn);
}
private void openModalDialogBtnActionPerformed(ActionEvent e) {
if (modalDialog == null) {
Window topWindow = SwingUtilities.getWindowAncestor(mainPanel);
modalDialog = new JDialog(topWindow, "Modal Dialog", ModalityType.APPLICATION_MODAL);
modalDialog.getContentPane().add(new DialogPanel().getMainPanel());
modalDialog.pack();
modalDialog.setLocationRelativeTo(topWindow);
modalDialog.setVisible(true);
} else {
modalDialog.setVisible(true);
}
}
private void openNonModalDialogBtnActionPerformed(ActionEvent e) {
if (nonModalDialog == null) {
Window topWindow = SwingUtilities.getWindowAncestor(mainPanel);
nonModalDialog = new JDialog(topWindow, "Non-Modal Dialog", ModalityType.MODELESS);
nonModalDialog.getContentPane().add(new DialogPanel().getMainPanel());
nonModalDialog.pack();
nonModalDialog.setLocationRelativeTo(topWindow);
nonModalDialog.setVisible(true);
} else {
nonModalDialog.setVisible(true);
}
}
public JPanel getMainPanel() {
return mainPanel;
}
}
class DialogPanel {
private static final Dimension DIALOG_SIZE = new Dimension(300, 200);
private JPanel dialogPanel = new JPanel();
public DialogPanel() {
dialogPanel.add(new JLabel("Hello from a dialog", SwingConstants.CENTER));
dialogPanel.setPreferredSize(DIALOG_SIZE);
}
public JPanel getMainPanel() {
return dialogPanel;
}
}
I would rather make a new instance of JFrame or a subclass, or call a new method who makes a new JFrame:
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == rejectionbutton){
JFrame frame = new JFrame("New Frame");
//or
makeNewFrame();
}
}
Another simple Layout-Manager is the BorderLayout, it´s the default Layout-Manager of the JFrame class.
new YourJFrameNameHere().setVisible(true);
Replace YourJFrameNameHere with the JFrame name.
Simple, no?

Categories