basic java Main method and update - java

Im new to pure java after been coding in javabased processing (processing.org) a lot. In processing you have a setup method (the constructor) and a draw method in the main class.
The draw method loops over and over again untill you close the program. In draw i run my methods from other classes.
How do I do this in java? For example in this code below for getting the counter to count?
public class Testing3 {
public static void main(String[] args) {
MyClass c = new MyClass();
System.out.println("c = " + c.getCount());
}
}
And the class:
public class MyClass {
private int value;
public MyClass() {
}
public void setCount(int startV) {
value = startV;
}
public int getCount() {
value++;
int counter = value % 10;
return counter;
}
}
I know I of course can put the printmessage in a while loop and loop it that way but I guess there are other ways?
I have also been using swing a bit through the GUI builder in netbeans. There I cannot reach my objects within the main method, getting the "non static variable cannot be referenced from a static content". only through functions like the one below. But what if I want to get my counter without pushing on a button i created in the builder etc?
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {}
I know its a newby question but Im a bit confused.

I didn't exactly understand your question (assuming there's only one question) , but I think this is what you're looking for
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
class Listener implements ActionListener{
int n;
JLabel label;
public Listener(int n,JLabel label){
this.n=n;
this.label=label;
}
#Override
public void actionPerformed(ActionEvent arg0) {
n++;
label.setText(""+n);
}
}
public class SwingTest {
public static void main(String[] args) {
int n=0;
JFrame frame= new JFrame("My First JAVA SWING App");
frame.setLayout(new FlowLayout());
JLabel label=new JLabel("value here");
JButton button=new JButton("click!!!");
button.addActionListener(new Listener(n,label));
frame.add(button);
frame.add(label);
frame.setSize(200, 100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
this should be on a file called SwingTest.java

Related

Java Swing Component("c") Cannot be Resolved

I'm currently stuck on a project at the moment component("c") cannot be resolved, I know I'm getting this issue as I'm trying to grab "c" from outside the class from the repaint method but have no idea how to get around this. As far as I'm concerned if I am able to grab "c" then my whole program would. Any help will be massively appreciated. thanks!
package adp.cwr2122;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
public class SomApplication extends JFrame {
private static final long serialVersionUID = 1L;
private final JProgressBar bar = new JProgressBar();
private final SoM som = new SoM(800,600);
public SomApplication() {
final JPanel mainPanel = new JPanel(new BorderLayout());
final JPanel southPanel = new JPanel(new BorderLayout());
final JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(ev -> doCancel());
this.bar.setMaximum(5000);
southPanel.add(this.bar);
southPanel.add(cancelButton, BorderLayout.EAST);
final SomComponent c = new SomComponent(this.som);
mainPanel.add(c);
mainPanel.add(southPanel, BorderLayout.SOUTH);
add(mainPanel);
pack();
setVisible(true);
this.som.initialise();
c.repaint();
final long start = System.currentTimeMillis();
while(SomApplication.this.som.range() > 0) {
SomApplication.this.som.doOne();
SomApplication.this.bar.setValue((int)((5000 * (SomApplication.this.som.maxRange() - SomApplication.this.som.range())) / SomApplication.this.som.maxRange()));
c.repaint();
}
final long elapsed = System.currentTimeMillis() - start;
System.out.println("Done " + elapsed);
}
private void doCancel() {
System.out.println( "Cancel button pressed");
}
private static class SomComponent extends JComponent {
private static final long serialVersionUID = 1L;
private final SoM som;
public SomComponent( final SoM som) {
this.som = som;
new Thread(new Runnable() {
public void run(){
queuePaint();
System.out.println("Thread is working");
}
}).start();
}
public void repaint() {
if(SwingUtilities.isEventDispatchThread()) {
c.repaint();
}
else {
SwingUtilities.invokeLater(c.repaint);
}
}
public void queuePaint() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.out.println("Queue Paint is being called");
setPaint(); }
});
}
public void setPaint() {
System.out.println("Paint is being called");
paintComponent(this.getGraphics());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(this.som.image().getWidth(), this.som.image().getHeight());
}
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
g.drawImage(this.som.image(), 0, 0, this);
repaint();
}
}
public static void launch() {
new SomApplication();
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new SomApplication();
}
});
}
}
As you have recognized yourself your problem is access to c in the repaint() method. You only declare c in the scope of the constructor of SomApplication, so everything outside that scope (read: outside the curly braces of the SomApplicaton constructor) has no idea what c is supposed to be, because it is not declared.
One way to resolve this is declaring c as a member of SomApplication. However you will run into an additional problem there. Your nested class is static, so if you declare c as a member of SomApplication, then SomComponent cannot be static in order to "see" c.
Having said all that there is something fishy with your code there. Because c is an instance of SomComponent and presumably you intend to update itself I then don't see why c is in repaint() to begin with. Your repaint() does not override the JComponent#repaint and your c is presumably supposed to be this.
It's possible I misunderstand something about your architecture, but are you sure you need the c at all in there? Why don't you call repaint() rather than c.repaint() in SomComponent?
If you took the code piece in your SomComponent#repaint method from some online example, take a look at whether you need that code at all. JComponent already comes with repaint(), so maybe this is just the result of a bad copy+paste. Not sure.

Inheritence of a JButton Java - Overriding Method Issue

I am wanting to set the visibility of a JButton to false in another class. So what I am doing is overriding the boolean function I created in StudentAccount named getWriteBtnVisibility() to change the visibility of the button in the HW class. So basically I want to make the JButton invisible in the StudentAccount. Since I want that button to be visible when a different type of account is logged in.
However, the way I am doing it seems not to be working. I have debugged my code and not understanding why it is not overriding the function. If I can get some guidance, I'd greatly appreciate it.
StudentAccount:
import java.awt.EventQueue;
public class StudentAccount extends AccountTemplate {
/**
* Launch the application.
*/
#Override
public String getHomeworkBtnName() {
return "Submit Assignment";
}
#Override
public boolean getWriteBtnVisibility() {
return false;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
StudentAccount window = new StudentAccount();
window.frmAccountTemplate.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
AccountTemplate:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class AccountTemplate extends HW {
protected JFrame frmAccountTemplate;
/**
* Launch the application.
*/
public String getHomeworkBtnName() {
return "Hw";
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
AccountTemplate window = new AccountTemplate();
window.frmAccountTemplate.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public AccountTemplate() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
protected void initialize() {
frmAccountTemplate = new JFrame();
frmAccountTemplate.setTitle(getFrameTitleName());
frmAccountTemplate.setBounds(100, 100, 450, 300);
frmAccountTemplate.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmAccountTemplate.getContentPane().setLayout(null);
JButton btnAssignment = new JButton(getHomeworkBtnName());
btnAssignment.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frmAccountTemplate.dispose();
HW.main(null);
}
});
btnAssignment.setFont(new Font("Tahoma", Font.BOLD, 16));
btnAssignment.setBounds(15, 51, 200, 29);
frmAccountTemplate.getContentPane().add(btnAssignment);
}
}
HW:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.filechooser.FileSystemView;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.awt.event.ActionEvent;
public class HW {
public JFrame frmHw;
/**
* Launch the application.
*/
public boolean getWriteBtnVisibility() {
return true;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
HW window = new HW();
window.frmHw.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public HW() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
protected void initialize() {
frmHw = new JFrame();
frmHw.setTitle("HW");
frmHw.setBounds(100, 100, 450, 300);
frmHw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmHw.getContentPane().setLayout(null);
JTextArea jTextArea1 = new JTextArea();
jTextArea1.setBounds(9, 11, 328, 197);
frmHw.getContentPane().add(jTextArea1);
JScrollPane scrollBar = new JScrollPane(jTextArea1);
scrollBar.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollBar.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
frmHw.getContentPane().add(scrollBar);
scrollBar.setBounds(13, 39, 413, 189);
JButton btnWriteText = new JButton("Write Text");
btnWriteText.setVisible(getWriteBtnVisibility());
btnWriteText.setBounds(154, 11, 115, 24);
frmHw.getContentPane().add(btnWriteText);
}
}
When you made AccountTemplate extend the HW class, every method that was redefined in AccountTemplate overrided the original method from HW. The getWriteBtnVisibility is checked from within the HW's initialize method, but AccountTemplate's initialize method overrides it. Now StudentAccount inherits the overridden method which does not check for the getWriteBtnVisibility boolean and so the visibility is not modified.
If I understand correctly what you're trying to do is to extend the layout using inheritance, however to do that you need to create seperate methods that create and initialize the interface components and call them as required from class. Now you've only created a seperate method for the button name and visibility, but the method that checks for the visibility boolean has been overridden and no longer gets called.
You will have to redesign your architecture so that:
There is only one JFrame field (unless you want multiple interfaces)
There is only one method that creates the JFrame and sets up the title
All generic interface components are created using a seperate (final) method and can be called when required by the class that inherits it
A simple example
class HW {
public JFrame frame;
public String getFrameName() {
return "HW";
}
public boolean getHWBtnVisibility {return true;}
void setupHWComponents() {
JTextField field = new JTextField();
// ...
this.frame.getContentPane().add(field);
JButton button = new JButton("HW");
button.setVisible(getHWBtnVisibility());
// ...
}
void initFrame() {
this.frame = new JFrame(getFrameName());
// ....
}
void initialize() {
initFrame();
setupHWComponents();
}
}
And
class AccountTemplate {
public void setupTemplateComponents() {
JTextField loginField = new JTextField("login");
super.frame.getContentPane().add(loginField);
// ...
}
#Override
public void initialize() {
// Setup Frame and HW components
// If you dont want HW components, replace with initFrame()
super.initialize();
setupTemplateComponents();
}
}
Then the StudentAccount class can likewise choose what components to use and initialize and which ones it doesn't want and then it can add its own components to the frame.
The initialize method that matters, that sets the button's visibility is the one that is called from the HW class, and that method is only called from within AccountTemplate's button's ActionListener here:
public void actionPerformed(ActionEvent e) {
frmAccountTemplate.dispose();
HW.main(null);
}
Notice that it is a call to the HW main method, and so it is a HW instance that is being created when this happens (since that is what HW main creates), not a StudentAccount instance. This is why your inheritance doesn't work -- there is no inheritance happening when the button is created.
Having said that, I have to state that this code is overly complex, much more than it needs to be, and misuses inheritance in a way that only serves to confuse. Don't use inheritance (or absolute positioning and null layouts) since you're just complicating things needlessly. Simply your code and you will thank me.
If this were my project,
I would create distinct JPanels (not JFrames) for each type of GUI
I would use inheritance only for the program's model, the logical non-GUI aspects of the code, and not for the views (the GUI classes), and would use it very cautiously.
I would swap views using a CardLayout and not swap JFrames

Java do method while JToggleButton is pressed

Objective
I am trying to achieve code that will call upon a method for the time the JToggleButton in Swing is pressed down. The MainCode.intGenerate method, which returns an List<Integer>, takes in aList<Integer>.
Restrictions
Random_gen_Button is declared as such and is unchangeable due to NetBeans guarding it. I can change it using notepad to open but It is not allowing me to change it for a reason so I shall not.
private JToggleButton RANDOMGENBUTTON;
Code
private void RANDOMGENBUTTONActionPerformed(java.awt.event.ActionEvent evt) {
if(RANDOMGENBUTTON.isSelected()) {
EXITBUTTON.setEnabled(false);
List<Integer> INPUTLIST = new ArrayList<Integer>();
while(RANDOMGENBUTTON.isSelected()) {
INPUTLIST = MainCode.intGenerate(INPUTLIST);
}
}else {
EXITBUTTON.setEnabled(true);
}
}
Possible Solution
I think this should be achievable with another Thread but I am not sure how to do this.
The Error
This code does not work because it freezes the GUI, I cannot press on the JToggle Button again resulting in an infinite loop.
Edit
intGenerate()
public static List<Integer> intGenerate(List<Integer> INLIST) {
Random Rand = new Random();
int RANDOMNUM = Rand.nextInt((9999999 - 1000000) + 1) + 1000000;
if(INLIST.isEmpty()) {
INLIST.add(randomNum);
}else {
while(INLIST.contains(randomNum)==true) {
RANDOMNUM = Rand.nextInt((9999999 - 1000000) + 1) + 1000000;
}
INLIST.add(RANDOMNUM);
}
return INLIST;
Use a java.swing.Timer for the other thread that periodically tells your component to update itself. In the example below, the timer's listener updates the button's text when the button is selected or the button's model says it's pressed.
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JToggleButton;
import javax.swing.Timer;
/**
* #see http://stackoverflow.com/a/38051563/230513
*/
public class Test {
private final Random r = new Random();
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JToggleButton button = new JToggleButton("0000");
f.add(button);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
Timer t = new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (button.isSelected() | button.getModel().isPressed()) {
button.setText(String.valueOf(r.nextInt(9000) + 1000));
}
}
});
t.start();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Test()::display);
}
}
As an aside, don't let the GUI editor dictate your design.

Java JTextField information access from another class

I am using a gui with JTextFields to collect some information and then a JButton that takes that infomration and writes it to a file, sets the gui visibility to false, and then uses Runnable to create an instance of another JFrame from a different class to display a slideshow.
I would like to access some of the information for the JTextFields from the new JFrame slideshow. I have tried creating an object of the previous class with accessor methods, but the values keep coming back null (I know that I have done this correctly).
I'm worried that when the accessor methods go to check what the variables equal the JTextFields appear null to the new JFrame.
Below is the sscce that shows this problem.
package accessmain;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class AccessMain extends JFrame implements ActionListener
{
private static final int FRAMEWIDTH = 800;
private static final int FRAMEHEIGHT = 300;
private JPanel mainPanel;
private PrintWriter outputStream = null;
private JTextField subjectNumberText;
private String subjectNumberString;
public static void main(String[] args)
{
AccessMain gui = new AccessMain();
gui.setVisible(true);
}
public AccessMain()
{
super("Self Paced Slideshow");
setSize(FRAMEWIDTH, FRAMEHEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
//Begin Main Content Panel
mainPanel = new JPanel();
mainPanel.setBorder(new EmptyBorder(0,10,0,10));
mainPanel.setLayout(new GridLayout(7, 2));
mainPanel.setBackground(Color.WHITE);
add(mainPanel, BorderLayout.CENTER);
mainPanel.add(new JLabel("Subject Number: "));
subjectNumberText = new JTextField(30);
mainPanel.add(subjectNumberText);
mainPanel.add(new JLabel(""));
JButton launch = new JButton("Begin Slideshow");
launch.addActionListener(this);
mainPanel.add(launch);
//End Main Content Panel
}
#Override
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
if(actionCommand.equals("Begin Slideshow"))
{
subjectNumberString = subjectNumberText.getText();
if(!(subjectNumberString.equals("")))
{
System.out.println(getSubjectNumber());
this.setVisible(false);
writeFile();
outputStream.println("Subject Number:\t" + subjectNumberString);
outputStream.close();
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass();
testClass.setVisible(true);
}
});
}
else
{
//Add warning dialogue here later
}
}
}
private void writeFile()
{
try
{
outputStream = new PrintWriter(new FileOutputStream(subjectNumberString + ".txt", false));
}
catch(FileNotFoundException e)
{
System.out.println("Cannot find file " + subjectNumberString + ".txt or it could not be opened.");
System.exit(0);
}
}
public String getSubjectNumber()
{
return subjectNumberString;
}
}
And then creating a barebones class to show the loss of data:
package accessmain;
import javax.swing.*;
import java.awt.*;
public class AccessClass extends JFrame
{
AccessMain experiment = new AccessMain();
String subjectNumber = experiment.getSubjectNumber();
public AccessClass()
{
System.out.println(subjectNumber);
}
}
Hardcoding the accessor method with "test" like this:
public String getSubjectNumber()
{
return "test";
}
Running this method as below in the new JFrame:
SelfPaceMain experiment = new SelfPaceMain();
private String subjectNumber = experiment.getSubjectNumber();
System.out.println(subjectNumber);
Does cause the system to print "test". So the accessor methods seem to be working. However, trying to access the values from the JTextFields doesn't seem to work.
I would read the information from the file I create, but without being able to pass the subjectNumber (which is used as the name of the file), I can't tell the new class what file to open.
Is there a good way to pass data from JTextFields to other classes?
pass the argument 'AccessMain' or 'JTextField' to the second class:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass(AccessMain.this); //fixed this
testClass.setVisible(true);
}
});
Then reading the value of 'subjectNumber'(JTextField value) from the 'AccessMain' or 'JTextField' in the second class:
public class AccessClass extends JFrame
{
final AccessMain experiment;
public AccessClass(AccessMain experiment)
{
this.experiment = experiment;
}
public String getSubjectNumber(){
return experiment.getSubjectNumber();
}
}
Also, you should try Observer pattern.
A simple demo of Observalbe and Observer
Observable and Observer Objects

Java Architecture - Question about ActionListener Conventions

I am making a user interface which shows graphs and manipulates graphs. The class extends JFrame implements ActionListener. The ActionListener then calls different classes to manipulate graphs depending on the action. This worked while the class had few ActionListeners; however, now the class is becoming unmanageable.
I know that in the interest of encapsulation, it would be best to have the ActionListener within the user interface class because it needs to access non-static components of the interface. However, it seems like there is a conflict between encapsulation and readability.
What I am proposing is breaking the class into one class for the interface and a second for the ActionListener and accessing the interface components statically. What I want to know is does this follow basic design conventions? And, if this is an acceptable approach would you place the main class in the user-interface class or the ActionListener class?
Not a duplicate question... but my answer should help with your question.
Short summery, my preference would be to have the JFrame class not implement ActionListener and then have a number of named inner classes withing the JFrame that do implement the ActionListener.
I would place the main in a class unto itself... and call it Main.
Here is some sample code for the way I like to do it:
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Main
{
private Main()
{
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
final FooFrame frame;
frame = new FooFrame();
frame.setupGUI();
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
and then the GUI:
import java.awt.FlowLayout;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class FooFrame
extends JFrame
{
private final JButton incrementBtn;
private final JButton decrementBtn;
private int value;
{
incrementBtn = new JButton("++");
decrementBtn = new JButton("--");
}
private class IncrementListener
implements ActionListener
{
public void actionPerformed(final ActionEvent evt)
{
increment();
}
}
private class DecrementListener
implements ActionListener
{
public void actionPerformed(final ActionEvent evt)
{
decrement();
}
}
public void setupGUI()
{
final LayoutManager layout;
layout = new FlowLayout();
setLayout(layout);
setupListeners();
addComponents();
}
private void setupListeners()
{
incrementBtn.addActionListener(new IncrementListener());
decrementBtn.addActionListener(new DecrementListener());
}
private void addComponents()
{
add(incrementBtn);
add(decrementBtn);
}
private void increment()
{
value++;
System.out.println("value = " + value);
}
private void decrement()
{
value--;
System.out.println("value = " + value);
}
}

Categories