I just want to set custom list model for ComboBox. The commented code also didn't worked. I completely don't know why!
I'm working in Intellij Community Edition under JDK 1.8
import jssc.SerialPortList;
import javax.swing.*;
import java.awt.*;
public class sampleForm extends JFrame {
private JComboBox comboBox1;
private JPanel panel1;
/*public sampleForm() {
super("title");
String[] portNames = SerialPortList.getPortNames();
setLayout(new FlowLayout());
comboBox1 = new JComboBox(portNames);
add(comboBox1);
}*/
public static void main(String[] args) {
JFrame frame = new JFrame("sampleForm");
frame.setContentPane(new sampleForm().panel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private void createUIComponents() {
// TODO: place custom component creation code here
String[] portNames = SerialPortList.getPortNames();
comboBox1 = new JComboBox(port);
}
}
Your class is already a JFrame, but you create another JFrame instance in the main method. So whatever you added in the sampleForm constructor has no affect visually because the sampleForm instance isn't the frame your showing. You're showing the new JFrame instance. So instead, do
public sampleForm() {
super("title");
String[] portNames = SerialPortList.getPortNames();
comboBox1 = new JComboBox(portNames);
panel1 = new JPanel(); // default FlowLayout
panel.add(comboBox1);
setContentPane(panel1);
}
public static void main(String[] args) {
sampleForm frame = new sampleForm("sampleForm");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
Also, see Initial Threads. Swing apps should be run on the Event Dispatch Thread.
Related
Hello I would like to ask how can I call my Main menu screen from MainScreen? and kindly explain a little more details about Listener.
below is my prepared code:
public class MainScreen {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(panel);
frame.setVisible(true);
}
private static void placeComponents(JPanel panel) {
JLabel WelcomeNote = new JLabel("Welcome");
panel.add(WelcomeNote);
JButton Start = new JButton("Start");
panel.add(Start);
//Insert action for Start button here
}
}
public class MainMenu {
public static void main(String[] args){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(panel);
frame.setVisible(true);
}
private static void placeComponents(JPanel panel) {
JLabel menuLbl = new JLabel("Main Menu");
panel.add(menuLbl);
}
}
What is wrong?
You cannot have two main methods in a single file in Java.
Program
Here is a demo program to change windows.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class First extends JFrame
{
JLabel jlb = new JLabel("Label in First Window");
JButton jb = new JButton("Next Window");
First()
{
super("First Windows");
//Set this frame
this.setSize(350,250);
this.setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Setting size of components
jlb.setBounds(10,10,200,40);
jb.setBounds(10,120,150,40);
add(jlb);
add(jb);
jb.addActionListener((e)->{
this.setVisible(false);
new Second();
});
setVisible(true);
}
}
class Second extends JFrame implements ActionListener
{
JLabel jlb = new JLabel("Label in Second Window");
JButton jb = new JButton("Prev. Window");
Second()
{
super("Second Window");
this.setSize(350,250);
this.setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Setting size of components
jlb.setBounds(10,10,200,40);
jb.setBounds(10,120,150,40);
add(jlb);
add(jb);
jb.addActionListener(this);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
this.setVisible(false);
new First();
}
}
class StartHere
{
public static void main(String[] args) {
Runnable r = ()->{
new First();
};
r.run();
}
}
Understanding the above program.
The StartHere class has a main method. It is just used for calling the first window you like. I could even call Second using new Second().
First and Second are similar codes.
Both of them have buttons. On each button (or JButton) I have added a method named addActionListner(this). This method fires up an ActionEvent which as you can see in Second class is captured by actionPerformed method. This method is declared in Functional Interface, ActionListener. The 'this' passed in Second class is you telling where the actionPerformed method is present in your code. The parameter is an ActionListener. Hence, you have to implement ActionListener for the class where you define actionPerformed.
Bonus
The First class doesn't seem to follow the norms described above. I passed a strange syntax. It is a new feature included in Java 8.
See this Oracle tutorial about Lambda Expressions.
I have 2 classes. Both implements runnable to create the GUI. The first one is the main, and the second one is the secondary class.
I want within the actionlistener of the main class to startup the secondary class.
Here is the code (the two classes are separated files):
public class Main implements Runnable
{
private JTextField txt1, txt2;
private JLabel lbl1, lbl2;
public void run()
{
JFrame frame = new JFrame("Secondary");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = frame.getContentPane();
JPanel background = new JPanel();
background.setLayout(new BoxLayout(background, BoxLayout.LINE_AXIS));
.........
// Horizontally adding the textbox and button in a Box
Box box = new Box(BoxLayout.Y_AXIS);
......
background.add(box);
pane.add(background);
frame.pack();
frame.setVisible(true);
}
private class SListener implements ActionListener
{
public void actionPerformed(ActionEvent a)
{
Secondary s = new Secondary();
}
}
public static void main (String[] args)
{
Main gui = new Main();
SwingUtilities.invokeLater(gui);
}
}
public class Secondary implements Runnable
{
private JTextField txt1, txt2;
private JLabel lbl1, lbl2;
public Secondary()
{
Secondary gui = new Secondary();
SwingUtilities.invokeLater(gui);
}
public void run()
{
JFrame frame = new JFrame("Secondary");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = frame.getContentPane();
JPanel background = new JPanel();
background.setLayout(new BoxLayout(background, BoxLayout.LINE_AXIS));
.........
// Horizontally adding the textbox and button in a Box
Box box = new Box(BoxLayout.Y_AXIS);
......
background.add(box);
pane.add(background);
frame.pack();
frame.setVisible(true);
}
}
I want to keep the code in two files, I don't want to mixed the two classes in one file.
As you can see from the code, in the Secondary class, in it's constructor I create an Instance of the Secondary class and I run the gui so that when the Instance of this class is created in the Main class, to run the gui.
Unfortunately this technique is not working.
Any ideas?
Thanks
The following line are complety wrong:
public Secondary(){
Secondary gui = new Secondary();
SwingUtilities.invokeLater(gui);
}
Each time you call new Secondary() somewhere in your code, the above code will be triggered, which in turn calls new Secondary() again, and again, and again, ... and your program is blocked.
You probably want to replace it either by
public Secondary(){
SwingUtilities.invokeLater(this);
}
which will avoid the loop, but this is weird behaviour for a constructor.
It makes much more sense to switch to an empty constructor (or delete it all together)
public Secondary(){
}
and rewrite your listener to
public void actionPerformed(ActionEvent a){
Secondary s = new Secondary();
SwingUtilities.invokeLater( s );
}
I would recommend that you completely re-design your program. I find that it is most helpful to gear my GUI's towards creation of JPanels, not top level windows such as JFrame, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via CardLayouts, wherever needed. I find that this greatly increase the flexibility of my GUI coding, and is exactly what I suggest that you do. So...
Your first class creates a JPanel that is then placed into a JFrame.
In the first class's ActionListener, create an instance of the 2nd class, place it into a JDialog (not a JFrame), and then display it.
For example,
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class TwoWindowEg {
public TwoWindowEg() {
// TODO Auto-generated constructor stub
}
private static void createAndShowGui() {
GuiPanel1 mainPanel = new GuiPanel1();
JFrame frame = new JFrame("Main GUI");
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 GuiPanel1 extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 650;
private GuiPanel2 guiPanel2 = new GuiPanel2(); // our second class!
private JDialog dialog = null; // our JDialog
public GuiPanel1() {
setBorder(BorderFactory.createTitledBorder("GUI Panel 1"));
add(new JButton(new LaunchNewWindowAction("Launch New Window")));
add(new JButton(new DisposeAction("Exit", KeyEvent.VK_X)));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class LaunchNewWindowAction extends AbstractAction {
public LaunchNewWindowAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
if (dialog == null) {
// get the Window that holds this JPanel
Window win = SwingUtilities.getWindowAncestor(GuiPanel1.this);
dialog = new JDialog(win, "Second Window", ModalityType.APPLICATION_MODAL);
dialog.add(guiPanel2);
dialog.pack();
}
dialog.setVisible(true);
}
}
}
class GuiPanel2 extends JPanel {
public GuiPanel2() {
setBorder(BorderFactory.createTitledBorder("GUI Panel 1"));
add(new JLabel("The second JPanel/Class"));
add(new JButton(new DisposeAction("Exit", KeyEvent.VK_X)));
}
}
class DisposeAction extends AbstractAction {
public DisposeAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Component comp = (Component) e.getSource();
Window win = SwingUtilities.getWindowAncestor(comp);
win.dispose();
}
}
Alternatively, you could swap JPanel "views" using a CardLayout, but either way, you will want to avoid showing two JFrames. Please have a look at The Use of Multiple JFrames, Good/Bad Practice?.
public class HandleUI {
public static void setUpUI(){
JPanel jPan = new JPanel();
FlowLayout flow = new FlowLayout();
jPan.setLayout(flow);
txtFld = new JTextField();
txtFld.setSize(550,5);
jPan.add(txtFld);
jPan.setSize(10,200);
MainClass.mainFrame.add(jPan);
int gapX = MainClass.mainFrame.getX()-(txtFld.getX()/2);
}
//Instance variables.
public static JTextField txtFld;
public JButton [] buttons;
}
public class MainClass {
public static void main (String [] args){
int frameX = Constants.FRAME_WIDTH;
int frameY = Constants.FRAME_HEIGHT;
mainFrame = new JFrame();
mainFrame.setSize(frameX,frameY);
mainFrame.setResizable(false);
mainFrame.setVisible(true);
HandleUI.setUpUI();
}
//Instance variables
public static JFrame mainFrame;
}
It's supposed to show JTextField, but as you might have guessed - JFrame shows nothing. I didn't type in imports on purpose, but they are all there. I can't find the problem. Can anyone help?
1.) Simply write:
JTextField tField = new JTextField(10);
Here In the constructor you are passing the number of columns, which is sufficient for a layout like FlowLayout to set the size of the JTextField
2.) The line mainFrame.setVisible(true); must be the last line of the main method. You need to put the code at main() method, inside SwingUtilities.invokeLater(...) thingy.
3.) Instead of setting size on the JFrame use JFrame.pack(), to set the window to the preferred size.
4.) Creation of unnecessary static members is a design flaw. Try to keep yourself away from such thingies.
5.) Read a bit about Concurrency in Swing
One Example Program for help(Use the order of lines as specified in this answer):
import java.awt.*;
import javax.swing.*;
public class Example {
private void displayGUI() {
JFrame frame = new JFrame("Example Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
JTextField tField = new JTextField(10);
contentPane.add(tField);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new Example().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
You have to call setVisible(true) on your JFrame AFTER having initialised your UI.
Simply pulling the following line:
HandleUI.setUpUI();
... right before:
mainFrame.setVisible(true);
... will do the trick.
As a side note, I'd like to point out that setting the size of your text field won't really work like you did. You probably would use setPreferredSize(Dimension) instead. Or, even better, organise your UI only using Layouts and not manually setting any component's size.
I have this class and the other one to connect to database and show me a table of the database this part of program works pretty well the problem explained below ,but no:
import java.awt.Color;
import java.awt.event.*;
import java.sql.SQLException;
import javax.swing.*;
public class ManagerInterface {
public static JFrame ManagerInterface = new JFrame("Manager Interface");
public ManagerInterface() {
StartInterfaceGUI();
}
public static JFrame getframe() {
return ManagerInterface;
}
private void StartInterfaceGUI() {
ManagerInterface.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ManagerInterface.setSize(1600, 900);
new ShowEmployee();
ManagerInterface.setVisible(true);
}
}
public static void main(String []args)
{
new ManagerInterface();
}
and this class:
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.sql.*;
import java.util.*;
import javax.swing.*;
import GUIManager.ManagerInterface;
public class ShowEmployee {
public static JInternalFrame frame = new JInternalFrame();
public JTable table = new JTable();
public JFrame mainframe = new JFrame();
public ShowEmployee() {
frame.add(table);
JScrollPane scroll = new JScrollPane(table);
frame.getContentPane().add(scroll, BorderLayout.SOUTH);
frame.setTitle("Employees");
frame.setResizable(true);
frame.setClosable(true);
frame.setMaximizable(true);
frame.setIconifiable(true);
frame.setSize(650, 400);
frame.pack();
frame.setVisible(true);
/* mainframe.add(frame);
mainframe.setSize(650, 400); //adding frame inside mainframe defined in this class
mainframe.pack();
mainframe.setVisible(true);*/
//ManagerInterface.getframe().add(frame); //adding the internalframe to manager interface frame
}
}
I use the ManagerInterface as a container for ShowEmployee, in this way:
in ManagerInterface I call a JFrame
the class ShowEmployee is represented by a JInternalFrame on which add a JTable.
I add the JInternalFrame to the frame of managerInterface class, that is defined by the line ManagerInterface.getframe.add.(frame), inserted in ShowEmployee.
The problem is the following:
if I define a frame(in this case mainframe) inside ShowEmployee and I add the internalframe i see this:
however, if I add the JInternalFrame to the frame ManagerInterface I see this:
In other words,i don't see the attributes row of the table represented by the ScrollPane,it is not visible at the inside of the frame managerInterface,
I define the scrollpane in this way, defined in ShowEmployee.
JScrollPane scroll = new JScrollPane (table);
frame.getContentPane (.) add (scroll BorderLayout.SOUTH);
As #kleopatra noted, follow java naming convention. variables start with lower case.
Why in the world are you naming the JFrame ManagerInterface when the class name is ManagerInterface?
Why in the world do you have two main methods? You only need it in the ManagerInterface, the launching class.
Just make ShowEmployee subclass JInternalFrame. Then just add it to the JFrame (that you are going to name something else) that is in ManagerInterface
public class ManagerInterface {
private Frame frame;
private ShowEmployees showEmployee;
public ManagerInterface() {
showEmployees = new ShowEmployees();
frame = new JFrame("MagagerInterface");
frame.add(new ShowEmployees());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativTo(null);
frame.setVisible(true);
}
}
public class ShowEmployees extends JInternalFrame {
public ShowEmployees() {
}
}
Adding on to 4. You should be adding JInternalFrame to JDesktopPanes and not JFrame
JDesktopPane desktop;
public ManagerInterface() {
showEmployees = new ShowEmployees();
desktop = new JDesktopPane();
desktop.add(showEmployees);
frame = new JFrame("MagagerInterface");
frame.setContentPane(desktop);
....
}
Run your Swing apps from the EDT
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new ManagerInterface();
}
});
}
See Initial Threads
The below doesn't cause a problem, but you should know that a parent can only have one parent container. So you trying to add the table to the frame and the scroll pane shouldn't be done. Just add the scroll pane
frame.add(table); <<---------------------Get Rid of MEEEE!
JScrollPane scroll = new JScrollPane(table);
frame.getContentPane().add(scroll, BorderLayout.SOUTH);
Here is a running example with all the above mentioned fixes.
import javax.swing.*;
public class ManagerInterface {
public JFrame frame = new JFrame("Manager Interface");
private ShowEmployee showEmployee;
private JDesktopPane desktop;
public ManagerInterface() {
showEmployee = new ShowEmployee();
desktop = new JDesktopPane();
desktop.add(showEmployee);
frame = new JFrame("MagagerInterface");
frame.setContentPane(desktop);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ManagerInterface();
}
});
}
}
class ShowEmployee extends JInternalFrame {
String[][] data = {{"Hello", "Hello", "Hello"},
{"Hello", "Hello", "Hello"}};
String[] cols = {"Col 1", "Col 2", "Col 3"};
public JTable table = new JTable(data, cols);
public ShowEmployee() {
JScrollPane scroll = new JScrollPane(table);
getContentPane().add(scroll);
setTitle("Employees");
setResizable(true);
setClosable(true);
setMaximizable(true);
setIconifiable(true);
pack();
setVisible(true);
}
}
When I launch my application, it launches the JFrame and loads up the JTabbedPane which contains the JScrollPane, yet it only shows one component inside it at a time. I have tried everything, and still I cannot solve the problem...
Here is my code:
package test;
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame{
public Main()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,500);
JPanel pane=new JPanel();
pane.setLayout(new BorderLayout());
UIManager.put("TabbedPane.contentOpaque", false);
JTabbedPane tabbedPane=new JTabbedPane();
JScrollPane scrollPane=new JScrollPane(pane);
tabbedPane.setPreferredSize(new Dimension(getWidth(),getHeight()));
for(int i = 0; i < 10; i++) pane.add(new JLabel("label22222222222222222222222222222222222222222222222222222222"+i));
//pane.add(scrollPane,BorderLayout.CENTER);
tabbedPane.add("Test",scrollPane);
add(tabbedPane);
}
public static void main(String[] args) {
Main main=new Main();
main.setVisible(true);
}
}
Please help me, I have no idea what I am doing wrong.
Your pane JPanel uses BorderLayout and you're adding components in a default fashion, or BorderLayout.CENTER. This is the expected behavior to show only the last component added.
You should consider using another layout such as GridLayout. Also, Google and read the "laying out components in a container" tutorial and understand the layouts that you're using.
Also, consider using a JList to display your data rather than a grid of JLabels.
As an aside, you should format your code for readability, not compactness. Don't put for loops on one line only. In fact all loops and blocks should go into curly braces to prevent your later editing your code, adding another line and thinking that it's in the loop when it's not.
Edit
For example, using a JList:
import javax.swing.*;
public class Main2 {
private static final int MAX_CELLS = 30;
private static void createAndShowGUI() {
final DefaultListModel<String> listModel = new DefaultListModel<>();
final JList<String> myList = new JList<>(listModel);
myList.setVisibleRowCount(8);
for (int i = 0; i < MAX_CELLS; i++) {
listModel.addElement("label22222222222222222222222222222222222222222222222222222222" + i);
}
JTabbedPane jTabbedPane = new JTabbedPane();
jTabbedPane.add("Test", new JScrollPane(myList));
JFrame frame = new JFrame("Main2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(jTabbedPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}