Can't access getter in external class - java

I am trying to access a getter function from another class after creating it in the main method of a program. I have tried accessing the function from other places, but IntelliJ still gives the same error: cannot resolve method "getCurrentDeviceInfo()"
The relevant code is as follows:
Main Method Of Program (currentMidiDeviceInfo is a public variable)
public static void main(String[] args)
{
optionsGUI = new optionsGUI();
currentMidiDeviceInfo = optionsGUI.getCurrentDeviceInfo();
}
OptionsGUI Class
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.swing.*;
import java.awt.*;
public class optionsGUI extends JFrame{
public MidiDevice.Info currentDeviceInfo;
public MidiDevice.Info getCurrentDeviceInfo() {
return currentDeviceInfo;
}
public optionsGUI() {
//Setup JFrame
setLayout(new FlowLayout());
setSize(new Dimension(250, 140));
//Get MIDI Device Info
MidiDevice.Info[] midiDeviceInfo = MidiSystem.getMidiDeviceInfo();
currentDeviceInfo = midiDeviceInfo[0];
//Setup Midi Device Selection Label
JLabel midiDeviceBoxLabel = new JLabel("Select an MIDI Device");
add(midiDeviceBoxLabel);
//Setup Midi Device Selection
JComboBox midiDeviceBox = new JComboBox(midiDeviceInfo);
add(midiDeviceBox);
//Setup OK and Cancel Buttons
JButton okButton = new JButton("OK");
okButton.addActionListener(e ->
{
currentDeviceInfo = (MidiDevice.Info) midiDeviceBox.getSelectedItem();
setVisible(false);
});
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(e -> this.setVisible(false));
//Setup Button Panel
JPanel buttonPanel = new JPanel();
buttonPanel.add(okButton);
buttonPanel.add(cancelButton);
add(buttonPanel);
}
}

Maybe you need to make the getCurrentDeviceInfo() method static? Or maybe move that code outside of the main method?

optionsGUI was declared as a JFrame, I have changed it now, and it works, thanks for the help!

Related

Java GUI, transitioning from one class to another

I am stumped and desperate for help. Been able to figure everything else out until I got into GUI's. What I am trying to do is go from the LogInPane (Log In Page) to JobSelectionGUI (Job Selection Page);
When I compile it runs how I want it to, but I can't figure out how to get my JFrame from LogInPaneGUI to close when it opens JobSelectionGUI, Tons of reading and videos and picking GUI's/Applying them is rough! I started with a GridLayout then switched to GridBagLAyout, then tried CardLayout and now back to GBL.
I don't use an IDE; I use SublimeText, so if something looks extremely elongated in my code, its because I had to write it out long for Sublime (or because I'm bad). All my code is separated into different classes so it stays neat and easy to debug. Every class has its own package, and every package has no more than 2 Methods. I work my butt off to keep my main completely empty!
Taking all criticism and advice!
MAIN:
package com.hallquist.kurtis.leigh.srcmain;
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.text.*;
// Class imports;
import JobSelection.*;
import LogInPane.*;
// My Main function. Used to pull packages and methods and compile them here;
public class SrcMainUserInformation{
public static void main(String[] args){
LogInPaneGUI logInGUI = new LogInPaneGUI();
logInGUI.logInPaneMainGUI();
}
}
First Class:
package LogInPane; // package name;
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon;
import JobSelection.*; //import for next GUI when LogInButton is clicked;
public class LogInPaneGUI{
private static final JFrame frame = new JFrame();
private static final int COLS = 10; // Max columns;
private static final JPanel panelForm = new JPanel(new GridBagLayout()); // layout
private static final JTextField fieldLogInName = new JTextField(COLS); //login
private static final JPasswordField logInPassword = new JPasswordField(COLS); //pw
private static final JButton logInButton = new JButton("Log In"); //login button
private static final JButton exitButton = new JButton("EXIT"); //system.exit button
private static final JButton newUser = new JButton("New User? Click here to sign up!"); // new user button
// Wigits on login page;
public LogInPaneGUI(){
GridBagConstraints c = new GridBagConstraints();
// Creates the panel that goes ontop of the JFrame;
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.LINE_END;
panelForm.add(new JLabel("Account Name: "), c);
c.gridy ++;
panelForm.add(new JLabel("Password: "), c);
c.gridy ++;
c.gridx = 1;
c.gridy = 0;
c.anchor = GridBagConstraints.LINE_START;
panelForm.add(fieldLogInName, c);
c.gridy++;
panelForm.add(logInPassword, c);
c.gridy++;
panelForm.add(logInButton, c);
c.gridy++;
panelForm.add(newUser, c);
c.gridy++;
panelForm.add(exitButton, c);
// Goes to fourm/website on newUser click;
newUser.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
System.out.println("Fourm/Website to sign up for game");
}
});
// Exits program on exitButton click;
exitButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
// Goes to JobSelectionGUI on logInButton Click;
logInButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
JobSelectionGUI jobSelecting = new JobSelectionGUI();
jobSelecting.jobSelectionJFrameGUI();
// frame.dispose();
// System.out.println("Will log you in when I set it up");
}
});
}
// Actual JFrame that everything goes ontop of;
public static void logInPaneMainGUI(){
JFrame frame = new JFrame("FirstProject");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(1080, 720);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.getContentPane().add(panelForm);
}
}
Second Class:
package JobSelection;
import java.awt.*;
import java.awt.event.ActionEvent.*;
import javax.swing.*;
import javax.swing.text.*;
// Mass import from JobSelection package; All base job information;
import JobSelection.JobInformationIndex.JobAmazonData.*;
import JobSelection.JobInformationIndex.JobBanditData.*;
import JobSelection.JobInformationIndex.JobLancerData.*;
import JobSelection.JobInformationIndex.JobSorcererData.*;
import JobSelection.JobInformationIndex.JobWitchData.*;
import LogInPane.*; // to return to login screen;
import JobSelection.*; // dont know if needed;
public class JobSelectionGUI{
private static JFrame frame = new JFrame();
private static JSplitPane jSplitPane = new JSplitPane();
private static JPanel leftPane = new JPanel();
private static JLabel logInCharacterName = new JLabel();
private static JTextField userCharacterName = new JTextField();
private static JButton logInAccept = new JButton("Accept");
private static JButton logInBack = new JButton("Back");
private static JTextArea firstGameIntroduction = new JTextArea();
private static JTextArea descriptionIntroduction = new JTextArea();
private static JTextArea jobSelectedInformation = new JTextArea();
private static JPanel allWidgits = new JPanel();
public JobSelectionGUI(){
JTextArea firstGameIntroduction = new JTextArea("\ Text.");
firstGameIntroduction.setLineWrap(true);
firstGameIntroduction.setWrapStyleWord(true);
JScrollPane areaScrollPane = new JScrollPane(firstGameIntroduction);
areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(250, 250));
areaScrollPane.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Introduction"),
BorderFactory.createEmptyBorder(5,5,5,5)),
areaScrollPane.getBorder()));
leftPane.add(areaScrollPane);
JTextArea descriptionIntroduction = new JTextArea(" Text.\n");
descriptionIntroduction.setLineWrap(true);
descriptionIntroduction.setWrapStyleWord(true);
JScrollPane areaScrollPaneTwo = new JScrollPane(descriptionIntroduction);
areaScrollPaneTwo.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPaneTwo.setPreferredSize(new Dimension(250, 250));
areaScrollPaneTwo.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("What to expect"),
BorderFactory.createEmptyBorder(5,5,5,5)),
areaScrollPaneTwo.getBorder()));
leftPane.add(areaScrollPaneTwo);
}
public static void jobSelectionJFrameGUI(){
JFrame frame = new JFrame("FirstProject");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1080, 720);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.getContentPane().add(leftPane);
}
}
You grossly overuse the static modifier and most of your fields should not in fact be static. I would venture to state that most if not all of your class's fields should be private instance fields.
The log-in window should not be a JFrame but rather a blocking or "modal" dialog, and for Swing that means using a modal JDialog or JOptionPane (which creates a modal JDialog behind the scenes)
A modal dialog will block the calling code when it is displayed
And if the dialog is modal, then you know when it is no longer visible since the calling code is unblocked. This is when you would query the state of the dialog's fields (using public getter methods, not calling static fields directly), and decide if the login was successful or not. If so, show your main GUI window or JFrame.
Another option is to yes, use CardLayout, but for this to work, all your major GUI classes should be geared towards creating JPanels, not JFrames. This way you can insert the panels where and when needed, including within top-level windows such as JFrames or JDialogs, within or JPanels, or swapped using a CardLayout.
Note that frame.dispose() isn't working for you because you shadow the frame field by re-declaring it logInPaneMainGUI() method.
public static void logInPaneMainGUI() {
// ***** this creates a new local JFrame variable called frame
JFrame frame = new JFrame("FirstProject");
// so calling frame.dispose() elsewhere will have no effect on this window
Don't do this, and the .dispose() method call will close the first window.
public static void logInPaneMainGUI() {
frame = new JFrame("FirstProject"); // this initializes the frame field
// so calling frame.dispose() elsewhere will have no effect on this window
Of course frame would have to be non-final or not-initialized previously. I still would recommend using a JDialog however, as well as moving out of the static world and into the instance world
Unrelated criticism:
Less chatty text in your question, text that is completely unrelated to your actual problem at hand, and more text that tells us useful information that helps us to understand your problem and your code, and thereby helping us solve the problem.

I have a small eror in my code here (swing-java-JFrame)

First I am a beginner in java. I'm making a window with small button and a label (with 0 in default position), when I click on the button the label will change to 1 and when I tap another click the button will be 2. But, I have an error in calling the method.
my code:
package prototype;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Prototype {
public static int count;
public static JLabel l;
public void Proto()
{
JFrame f = new JFrame();
JButton b = new JButton("click");
JLabel lo = new JLabel("0");
JPanel p = new JPanel();
f.setBounds(120,120,500,500);
b.addActionListener(new MyAction());
p.add(lo);
p.add(b);
f.getContentPane().add(p,BorderLayout.CENTER);
f.show();}
public class MyAction implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
count++;
l.setText(Integer.toString(count));}
public static void main(String[] args) {
//I want to call the proto method but it give me an eror
new proto();
}}}
public class Prototype extends JFrame{
private static int count;
private JLabel l;
public Prototype() {
super();
JButton b = new JButton("click");
l = new JLabel("0");
JPanel p = new JPanel();
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
count++;
l.setText(Integer.toString(count));
}
});
p.add(l);
p.add(b);
this.getContentPane().add(p, BorderLayout.CENTER);
this.pack();
this.setVisible(true);
}
public static void main(String...args){
Prototype p=new Prototype();
}
}
I changed the method to a constructor, to have the possibility of creating a object of type Prototype and directly create a frame with it. Also I extended the class with JFrame to not need to create an extra JFrame. Next step was to remove the ActionListener class and creating a new ActionListener while adding it to the button. In my eyes this is useful if you have several buttons with different functionalities, so you can see the function of the button directly just by looking at the code of the button. and the last step was to create a new Object of type Prototype in the main method
If I we're you use a SwingWorker instead of manually setting the text of JLabel. Because this is not a proper way updating your GUI. This should be done using SwingWorker. Please read about publish and processmethod.

Calling different screen thru button from a screen

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.

Nothing is appearing when i switch JPanels

Im rather new at Java, I am have created a home page and a few buttons, When i click one of the buttons it sets the homepage panel visibility to false, opens a new class and sets that classes Jpanel to visible.
homePanel.setVisible(false);
Goodsin Barcode = new Goodsin();
Goodsin.setVisible(true);
However once it opens the new class "Goodsin" it wont show any of the Buttons or TextFileds. I know it is opening the new class as a System.out.println prints to the console but nothing displays in the JFrame and i do not know why.
Here is my code of the new class
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Goodsin {
public JPanel Goodsin;
public JTextField item1;
public String code;
public JButton btn1;
public Goodsin() {
System.out.println("TEST");
Goodsin = new JPanel();
item1 = new JTextField(10);
btn1 = new JButton("Look up Barcode");
Goodsin.setVisible(true);
Goodsin.add(item1);
item1.setSize(80, 30);
Goodsin.add(btn1);
btn1.setSize(80, 30);
}
public void getString(String code) {
System.out.println(code);
}
}
Im sure i am not doing something correct with the Jpanel or adding the textfields or button but all the answers i have seen so far havnt worked.
I suggest you add your panels to a JFrame. You can either do this by extending JFrame from the class or simply instantiating one in your constructor. Then you can simply add and remove (or set visible/invisible) as you wish. Be sure to validate your JFrame/JPanel after changing visibility though.
Try to do something like this:
Goodsin = new JPanel();
item1 = new JTextField(10);
btn1 = new JButton("Look up Barcode");
item1.setSize(80, 30);
Goodsin.add(item1);
btn1.setSize(80, 30);
Goodsin.add(btn1);
JFrame frame = new JFrame("JFrame Example");
Goodsin.setLayout(new FlowLayout());
frame.add(Goodsin);
I suggest you try the following code :
public class Goodsin extends JFrame{
public static void main(String[] args) {
Goodsin ui = new Goodsin();
JTextField item1 = new JTextField(10);
JButton btn1 = new JButton("Look up Barcode");
JPanel centralPanel = new JPanel(new FlowLayout());
centralPanel.add(item1);
centralPanel.add(btn1);
item1.setSize(80, 30);
btn1.setSize(80, 30);
ui.add(centralPanel);
ui.pack();
ui.setVisible(true);
}
}
Everything is done in the main method in my example, however you still can improve this code and refactor it in a better way.
just you have to set Bounds of Goodsin panel or set Size and add in home page frame

Java GUI - JButton opens another frame from another class

i'm having trouble to get the 2nd frame to display the GUI Components. i've opened the frame using the JButton from the 1st frame.
Here's the screen shot
This is the first frame - ClientModule.java
2nd frame - ClientMenu.java
Here's the codes i've tried
ClientModule.java
import java.net.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ClientModule extends JFrame implements Runnable{
private JPanel panel;
private JFrame frame;
private JLabel titleLbl, userLbl, passLbl, hostLbl, portLbl, ipLbl;
private JTextField userTxt, hostTxt, portTxt, ipTxt;
private JPasswordField passTxt;
private JButton loginBtn;
public static void main(String[] args)
{
new ClientModule().run();
}
public ClientModule()
{
frame = new JFrame("DMS(Drawing Message System)");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
panel = new JPanel();
panel.setPreferredSize(new Dimension(500,500));
panel.setLayout(new FlowLayout());
titleLbl = new JLabel("LogIn to Drawing Message System(DMS)");
titleLbl.setFont(new Font("Rockwell Condensed",Font.BOLD,28));
userLbl = new JLabel("Username:");
passLbl = new JLabel("Password:");
hostLbl = new JLabel("Hostname:");
portLbl = new JLabel("Port No.:");
ipLbl = new JLabel("IP Address:");
userTxt = new JTextField();
userTxt.setPreferredSize(new Dimension(100,30));
passTxt = new JPasswordField();
passTxt.setEchoChar('*');
passTxt.setPreferredSize(new Dimension(100,30));
portTxt = new JTextField();
portTxt.setPreferredSize(new Dimension(100,30));
ipTxt = new JTextField();
ipTxt.setPreferredSize(new Dimension(100,30));
hostTxt = new JTextField();
hostTxt.setPreferredSize(new Dimension(100,30));
loginBtn = new JButton("Login!");
loginBtn.setPreferredSize(new Dimension(90,30));
loginBtn.addActionListener(new LoginBtnListener());
panel.add(titleLbl);
panel.add(userLbl);
panel.add(userTxt);
panel.add(passLbl);
panel.add(passTxt);
panel.add(hostLbl);
panel.add(hostTxt);
panel.add(portLbl);
panel.add(portTxt);
panel.add(ipLbl);
panel.add(ipTxt);
panel.add(loginBtn);
frame.add(panel);
}
private class LoginBtnListener implements ActionListener
{
#SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent action)
{
//thinking this frame will close after ClientMenu's frame is open
ClientModule client = new ClientModule();
client.setVisible(false);
ClientMenu menu = new ClientMenu();
menu.setVisible(true);
}
}
public void run()
{
frame.pack();
frame.setVisible(true);
}
}
ClientMenu.java
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class ClientMenu extends JFrame{
JFrame frame;
JPanel panel;
JLabel titleLbl;
JButton sendBtn,receiveBtn,logoutBtn;
public ClientMenu()
{
frame = new JFrame("Drawing Message System(DMS)");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.setPreferredSize(new Dimension(500,500));
titleLbl = new JLabel("Main Menu");
titleLbl.setFont(new Font("Rockwell Condensed",Font.BOLD,28));
sendBtn = new JButton("Send a Drawing");
sendBtn.setPreferredSize(new Dimension(100,30));
receiveBtn = new JButton("Receive a Drawing");
receiveBtn.setPreferredSize(new Dimension(100,30));
logoutBtn = new JButton("Logout");
logoutBtn.setPreferredSize(new Dimension(100,30));
logoutBtn.addActionListener(new LogoutBtnListener());
panel.add(titleLbl);
panel.add(sendBtn);
panel.add(receiveBtn);
panel.add(logoutBtn);
frame.add(panel);
}
private class LogoutBtnListener implements ActionListener
{
//#SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent action)
{
ClientModule client = new ClientModule();
client.setVisible(true);
ClientMenu menu = new ClientMenu();
menu.setVisible(false);
}
}
public static void main(String[] args)
{
new ClientMenu().run();
}
public void run()
{
frame.pack();
frame.setVisible(true);
}
}
I'm not sure if i'm missing something, or coded something wrong, or something else. I've already searched and tried..
any help and understanding is appreciated (:
I managed to get the second frame displayed (including its contents) by adding a call to the run() method:
ClientMenu menu = new ClientMenu();
menu.setVisible(true);
menu.run();
That being said, there are quite some problems with your code:
You have a main method in each of your classes. You should have only 1 main method per application. Since ClientModule seems to be the first Frame you want to have opened, your might want to keep the main method there and remove the one in the other class.
You have a run() method in each class. Personally, I tend to avoid naming methods like this, since it might cause confusion with the run() method which needs to be overridden when dealing with threads. You are clearly attempting to do some multi threading in your ClientModule, but will not work. Please look into this concurrency tutorial to better understand threads. You should also understand that you should never call run() yourself. The tutorial should make that clear.
Swing applications are started a little bit differently that other applications. Please refer to this tutorial for more information.
You have both your classes extend JFrame but then, provide your own. This results in other JFrames being created, which is what happened in my case (I get 2 JFrames per instantiation). If you want your class to behave like a JFrame, consider extending it, if you want to use a JFrame, then compose your class of one, not both (at least not in this case).
Lastly, to get rid of the previous JFrame you could call dispose() on the it. That being said, the approach usually is to use the Card Layout. This would allow you to have 1 frame with multiple content.
Sorry for the long post, but please consider re factoring as per the above prior to continuing.
You can use the setVisible property to 'true' or 'false'.

Categories

Resources