Call function in another class - java

Hello I'm facing this problem:
I created a button in class Luncher, when I click it I want to call a function in another class (Main) but I dont have a result.
However when i define (Main) class in run mode I get the intended result. What is the problem ?
This work for me :
When i set Main.class in run mode
And this not work :/ :
When i click in button to show Main.class
This is the code for the runable class (Luncher):
public class Luncher extends javax.swing.JFrame {
public Luncher() {
setSize(600,400);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
JButton jButton1 = new javax.swing.JButton();
jButton1.setText("CLIC ON ME !");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
Main example = new Main();
example.doThis();
}
});
GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(147, 147, 147)
.addComponent(jButton1)
.addContainerGap(180, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(108, 108, 108)
.addComponent(jButton1)
.addContainerGap(169, Short.MAX_VALUE))
);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Luncher().setVisible(true);
}
});
} }
And the second class is Main:
public class Main extends javax.swing.JFrame {
private static GUI gameGui = new GUI(); //GUI its a JFrame class
private static CardLayout card = new CardLayout();
private static JPanel content = new JPanel();
public Main(){
doThis();
}
public static void doThis (){
content.setLayout(card);
gameGui.setVisible(true);
gameGui.add(content);
gameGui.repaint();
gameGui.revalidate();
card.show(content);
}
public static void main (String [] args) {
} }

You have a few basic solutions available to you.
You could...
Pass a reference of Main to Luncher. This way, when you want to, you can just call the functionality of Main you need to.
This is not the best solution, as it couples Launcher to Main, making it difficult to re-use the code and possibly exposing functionality (of Main) to Launcher, which Launcher should have access to.
You could...
You could use a delegate or observer pattern...
Define an interface (or contract) which Launcher requires delegates to implement in order to perform the functionality it requires.
public interface LauncherDelegate {
//...
}
You would then have Main implement this interface
public class Main extends javax.swing.JFrame implements LauncherDelegate {
//...
and pass a reference of itself to Launcher
public class Luncher extends javax.swing.JFrame {
private LauncherDelegate delegate;
public Luncher(LauncherDelegate delegate) {
this.delegate = delegate
//...
This way, Launcher can only call the functionality described in the contract, it decouples the code, as any implementation of LauncherDelegate can be used and Launcher won't care, making the code more re-usable and configurable.

Related

Java Swing GUI closing randomly

My problem is quite weird: even if I create a JFrame with literally nothing in it, so it should just display a white window, but it crashes after doing anything with it. For example, when I resize the window, the new, resized area will be black in most cases (or sometimes be the right color I really don't know why) and it will either just close or display "Not responding" and then close after a few seconds.
GUI class:
public class GUI extends JFrame {
private static JFrame frame;
public GUI() {
frame = new JFrame();
frame.setTitle("test");
frame.getContentPane().setLayout(new FlowLayout());
frame.pack();
frame.setVisible(true);
}
}
Main class:
public class Main {
public static void main(String[] args) {
GUI gui = new GUI();
}
}
And here's an image exactly showing the behavior:
Why does it behave like this? It's most definitely not because of the code, I think. It must be something else. I tried reinstalling Java, didn't help out. Switched from SDK 13 to 1.8.0_171, nothing. Older programs using Swing also suddenly don't work anymore and behave the same. Any ideas?
Always start your GUI from the event dispatching thread to avoid unwanted behavior.
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI();
}
});
}
See the javadoc: invokeLater
Try this (width 400, height 300):
public class GUI extends JFrame {
private static JFrame frame;
public GUI() {
frame = new JFrame();
frame.setTitle("test");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
frame.pack();
frame.setVisible(true);
}
}

Java Netbeans: How to open the JPanel from another class?

I have a main.java file which I like to use to call the GUI made in JPanel.
It's my first NetBeans experience though, so be gentle :-) ...
It fails to compile; the error i get is :Erroneous sym type: main.GUI.GUI (which makes sense as it is interpreted).
But now: HOW DO I FIX IT??
I've tried GUI.GUI(); as well, but without positive results..
(I'm used to programming C++, but since import is not a true option in java (or is it?).
My main.java:
package main;
public class Main {
public static void main(String[] args) {
GUI obj = new GUI();
obj.GUI();
}
}
My GUI.java file:
package main;
public class GUI extends javax.swing.JPanel {
public GUI() {
initComponents();
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}
}
If I understand your question correctly you want to display the GUI from your Main class. One thing to keep in mind is that a JPanel itself cannot be displayed. It must be added to a JFrame before it shows. Try something like:
package main;
public class Main {
public static void main(String[] args) {
GUI obj = new GUI(); // creates your panel
JFrame frame = new JFrame("some title"); // creates the frame
frame.add(obj);
frame.setSize(200,300);
frame.setVisible(true);
}
}
GUI obj = new GUI();
it created new object of GUI. So, the constructor is operated already. The constructor method is special method, that plays when new object is created from the class.

components in Jdialog not shown

My application is created using Netbeans IDE (8.0.2).
I have created a JFrame which contains a JTable bound to a Database (using JPA).
I have added a "Refresh" button which is used to "refresh" the JTable data directly from the database.
I want a "Please wait" message to be displayed while data is being fetched.
For this I implemented a JDialog_PleaseWait class which extends JDialog.
For some strange reason, although the JDialog is shown the jLabel it includes does not show up...
The JDialog_PleaseWait class is :
public class JDialog_PleaseWait extends javax.swing.JDialog {
//constructor for PleaseWait jDialogs
public JDialog_PleaseWait(String messageToDisplay){
initComponents();
this.jLabel_WaitMessage.setText(messageToDisplay);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jLabel_WaitMessage = new javax.swing.JLabel();
setTitle("Please wait...");
setAlwaysOnTop(true);
setBackground(new java.awt.Color(227, 248, 115));
setModalityType(java.awt.Dialog.ModalityType.MODELESS);
setResizable(false);
setType(java.awt.Window.Type.POPUP);
jLabel_WaitMessage.setBackground(new java.awt.Color(242, 253, 153));
jLabel_WaitMessage.setText("WaitMessage");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel_WaitMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 271, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel_WaitMessage)
);
pack();
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel jLabel_WaitMessage;
// End of variables declaration//GEN-END:variables
}
The refresh JButton calls a method named "reload" which initially it must display the jDialog and perform the rest of its tasks afterwards.
More specifically :
public void reload(){
jTable_Activities.setEnabled(false); // freezes the JTable
JDialog_PleaseWait pleaseWaitDialog = new JDialog_PleaseWait("Communicating with database server...."); // create a new PleaseWait JDialog
pleaseWaitDialog.pack();
pleaseWaitDialog.setLocationRelativeTo(this); //relative to this frame
pleaseWaitDialog.setVisible(true); //display the JDialog
.... ....
// runs a DB query and updates a JTable
.... ....
So, for some reason the JDialog window pops up but the jLabel is not shown...
I(think I) have done the (exact?) same thing with other JDialogs which work fine but for some strange reason this JDialog does not work properly...
Any hint?
Your likely problem is that you're fetching your data on the Swing event thread (I don't see any code above where you use Thread/Runnable/SwingWorker or the like, and hence my assumption), and that this is tying up the event thread and preventing it from doing its chores -- including drawing the label to the JDialog. The solution: do the data fetching in a background thread such as by using a SwingWorker.
Here's an example that demonstrates what I mean. The code creates two JButtons, one which displays a JDialog for 2 seconds with a Thread.sleep(...) running on the Swing event thread during that 2 seconds, the other with the Thread.sleep(...) running in a background thread. Compile and run the code to see what happens.
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class PleaseWaitDialogTest extends JPanel {
protected static final long SLEEP_TIME = 2000L;
public PleaseWaitDialogTest() {
add(new JButton(new ShowWaitDialog("Without Thread", KeyEvent.VK_O, false)));
add(new JButton(new ShowWaitDialog("With BG Thread", KeyEvent.VK_W, true)));
}
private class ShowWaitDialog extends AbstractAction {
private boolean useBackgroundThread;
private JDialog dialog;
public ShowWaitDialog(String name, int mnemonic,
boolean useBackgroundThread) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.useBackgroundThread = useBackgroundThread;
}
#Override
public void actionPerformed(ActionEvent e) {
// create dialog in a lazy way
if (dialog == null) {
Window ancestorWindow = SwingUtilities
.getWindowAncestor(PleaseWaitDialogTest.this);
String title = "Dialog: " + getValue(NAME);
dialog = new JDialog(ancestorWindow, title,
ModalityType.MODELESS);
dialog.getContentPane().setLayout(new GridBagLayout());
dialog.add(new JLabel("Please Wait"));
dialog.setPreferredSize(new Dimension(250, 150));
dialog.pack();
dialog.setLocationByPlatform(true);
}
dialog.setVisible(true);
// since the dialog is non-modal, this code will run immediately after
// the dialog has been set visible
CloseRunnable closeRunnable = new CloseRunnable(dialog, SLEEP_TIME);
if (useBackgroundThread) {
// run the Runnable in a background thread
new Thread(closeRunnable).start();
} else {
// run the Runnable directly on the Swing event thread
closeRunnable.run();
}
}
}
private class CloseRunnable implements Runnable {
protected JDialog dialog;
private long sleepTime;
public CloseRunnable(JDialog dialog, long sleepTime) {
this.dialog = dialog;
this.sleepTime = sleepTime;
}
#Override
public void run() {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
// the dialog *must* be closed on the Swing event thread
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (dialog != null) {
dialog.setVisible(false);
}
}
});
}
}
private static void createAndShowGui() {
PleaseWaitDialogTest mainPanel = new PleaseWaitDialogTest();
JFrame frame = new JFrame("Test");
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();
}
});
}
}

Controlling JComponents from other classes

Is it possible to control instances like variables, jcomponents, timer in other external classes?
For example this is my Class1
public class Class1 extends JFrame {
JLabel lbl = new JLabel("Hello");
public Class1() {
super("Class1");
Container c = getContentPane();
setLayout(null);
c.add(lbl);
lbl.setBounds(0,0,100,20);
Class2.process();
setSize(200,100);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String var[]) {
new Class1();
}
}
You can see there's Class2.process();
Here's the other class externally but in the same folder
public class Class2 {
public static void process() {
// I want to control lbl from Class1 class inside this method like
// lbl.setVisible(false);
}
public static void main(String args[]) {
//
}
}
Is it possible? Sorry. I can't find answers on other website.
You have to pass the instance of JLabel e.g.;
JLabel lbl = new JLabel("Hello"););
Class2.process(lbl);
public class Class2 {
public static void process(JLabel lbl) {
// I want to control lbl from Class1 class inside this method like
lbl.setVisible(false); // this will change your Class1 Jlabel
}

Inheritting from custom JPanel using NetBeans GUI Builder

ContainerPanel is a custom JPanel class using a BorderLayout. The SOUTH contains a JPanel with a button. I want the CENTER to be an instance of another custom JPanel, say AbstractPanel, which provides an abstract method which will be called when the button is clicked. I also want to set this JPanel programmatically (at run-time). So far, I can do all of this as you can see in the following code (some of which is generated by the NetBeans GUI Builder):
package jpaneldemo;
import java.awt.BorderLayout;
public class ContainerPanel extends javax.swing.JPanel {
public ContainerPanel() {
initComponents();
}
public ContainerPanel(AbstractPanel abPanel) {
initComponents();
this.abPanel = abPanel;
this.add(this.abPanel, BorderLayout.SOUTH);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
private void initComponents() {
buttonPanel = new javax.swing.JPanel();
okButton = new javax.swing.JButton();
setLayout(new java.awt.BorderLayout());
okButton.setText("OK");
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okButtonActionPerformed(evt);
}
});
buttonPanel.add(okButton);
add(buttonPanel, java.awt.BorderLayout.PAGE_END);
}
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {
this.abPanel.abstractMethod();
}
// Variables declaration - do not modify
private javax.swing.JPanel buttonPanel;
private javax.swing.JButton okButton;
// End of variables declaration
private AbstractPanel abPanel = null;
}
I also created the AbstractPanel class:
package jpaneldemo;
public abstract class AbstractPanel extends javax.swing.JPanel {
public AbstractPanel() {
initComponents();
}
protected abstract void abstractMethod();
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
private void initComponents() {
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}
// Variables declaration - do not modify
// End of variables declaration
}
Now I want to create subclasses of this AbstractPanel class which I can edit in the NetBeans GUI. Typically, I right-click on a package name in the Projects window and then navigate to "New -> JPanel..." to create a custom JPanel. How do I get AbstractPanel to appear in the "New" menu so that I can edit the new class with the NetBeansGUI Builder? Or is there another way to accomplish the same thing?
If your intention is to provide a "template" component that can then be added to the palette and included in other containers, then yes you can.
Have a read through FaqFormCustomContainerBean
The basic idea (apart from creating a BeanDescriptor is you will need to provide a "content" panel of some kind, where additional content can be added at design time.
Now, if you're interested in providing a custom template, that's something I've not done before.
You could try reading through http://netbeans.org/competition/win-with-netbeans/customize-java-template.html. It may be a little out of date, but might help you in the right direction

Categories