Sorry if this question will sound too chaotic, feel free to edit it.
I have an application made entirely in netbeans, which uses SingleFrameApplication and auto-generated the GUI code, named "MyApp", and FrameView, named "MyView". Now, the MyApp somehow has the main() function, but the MyView has all the graphic elements..
I don't entirely understand how that happens, so used it as black box (it somehow created the window, I didn't have to care why). But now, I need the window to be only a window, opened by another JFrame. I don't know, how to accomplish that.
MyApp, which is extending SingleFrameApplication, have these methods:
public class MyApp extends SingleFrameApplication {
#Override protected void startup() {
show(new MyView(this));
}
#Override protected void configureWindow(java.awt.Window root) {
}
public static MyApp getApplication() {
return Application.getInstance(MyApp.class);
}
public static void main(String[] args) {
launch(MyApp.class, args);
}
}
MyView has these methods:
public class MyView extends FrameView {
public MyView(SingleFrameApplication app) {
super(app);
initComponents();
}
private void initComponents() {
//all the GUI stuff is somehow defined here
}
}
Now, I have no clue how the two classes work, I just want this window, defined in MyView, to appear after another window, "ordinary" JFrame. How can I call this MyApp/MyView?
But now, I need the window to be only a window, opened by another JFrame. I don't know, how to accomplish that.
1.) It's not just a window - it's a
Swing Framework Application (Ah, the
perils of GUI builders...); and -
2.) You haven't specified how you want
it "opened by another JFrame";
but something like this should work if you're launching it via a JButton -
JButton launchMyApp = new JButton("launch");
launchMyApp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
String[] args = {};
Application.launch(MyApp.class, args);
}
});
Related
I have a problem working with instances of different objects and this is what happens:
I have been developing a small game in Java (Swing & AWT) for a while and I have the following classes:
App.java
Play.java
Event.java
GameScene.java
MenuScene.java
Timer.java
Where:
App extends JFrame and is a frame with the main function of the application (main), this class creates the game window, and only exists this JFrame
The MenuScene and GameScene classes are scenes of the application, for example when you see the menu and you want to see the highest score, it is a scene, the levels of game are a scene, etc., but in this case I have only two scenes and I have represented them in JPanels: MenuScene extends JPanel and creates the game menu (buttons, images, etc.), the same applies to the GameScene class, this also extends JPanel and creates the game.
The other classes (Play, Event, Timer) are simple classes, they have the "logic of the game", keyboard control, timers, game operation and are instantiated in three global variables of the GameScene class.
Everything starts with App, creates an instance of it and in its constructor calls a method to "create" the menu (MenuScene.java). Now the menu has a JButton that when pressed "creates" the game (GameScene.java) and this class has a JButton to return to the menu at any time ... It is here where I have problems because if I am playing and I return to the menu Game still exists and I can lose, it does not make sense, it is as if you play but instead of seeing the game you see the menu, interestingly the graphic part works excellent, ie if I press a button it removes what I have and draws the scene that I want it quickly. It is because Play, Timer and Event are instantiated or "exist" in memory if I am not mistaken. So if I press again the "create game" JButton I would recreate a second instance of GameScene? And so infinitely for MenuScene and GameScene. Is there a solution to this? How do you think I should structure the application?
I give you an outline of the most important classes:
App.java
public class App extends JFrame {
private JPanel rootPanel;
public App() {
//Define frame
...
runScene(new MenuScene(this));
}
public void runScene(JPanel scene) {
destroyScene();
rootPanel.setBackground(scene.getBackground());
rootPanel.add(scene);
rootPane.validate();
rootPanel.repaint();
}
private void destroyScene() {
rootPanel.removeAll();
rootPanel.revalidate();
rootPanel.repaint();
}
public static void main(String[] args) { //Main
new App();
}
}
MenuScene.java
public class MenuScene extends JPanel {
private App app;
public MenuScene(App app) {
this.app = app;
//Define JPanel
...
buttonStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
app.runScene(new GameScene(app));
}
});
}
}
GameScene.java
public class GameScene extends JPanel {
private App;
private Play;
private Timer;
private Event; //Define controls (keyboard)
public GameScene(App app) {
this.app = app;
//Define JPanel, Play, Timer and Event
...
buttonBackMenu.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
app.runScene(new MenuScene(app));
}
});
}
}
Play.java
public class Play {
private JLabel[][] x;
public Play(JLabel[][] x) { //This matrix is important (is an reference), is instanced in GameScene, this is an problem?
this.x = x;
//Define others variables
}
}
I appreciate any help.
I have found a somewhat peculiar solution, but I do not know if it is the best:
The best way is that since the GC does not select the active timers then it is better to stop them and match the other objects to null. Using the Singleton pattern I have a single instance of a Frame, that same instance would be used in any class (Scene) that wants to run another scene, here an implementation:
App.java
public class App extends JFrame {
private JPanel rootPanel;
private static App app;
private App() {
super("x");
createApp();
}
public static App getInstance() {
if (app == null) {
app = new App();
}
return app;
}
private void createApp() {
//Define JFrame, rootPanel, buttons, etc ...
}
public void runScene(JPanel scene) {
rootPanel.removeAll();
rootPanel.add(scene);
rootPanel.revalidate();
rootPanel.repaint();
}
public static void main(String[] args) { //Main
getInstance().runScene(new MenuScene());
}
}
GameScene.java
public class GameScene extends JPanel {
private Play p;
private Timer t;
private Event e; //Define controls (keyboard)
private JLabel[][] mat;
public GameScene() {
//Define JPanel, Matrix, Play, Timer and Event
...
buttonBackMenu.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent x) {
This method is useful to create another scene for example from another instance other than this (GameScene)
changeScene(new MenuScene());
}
});
}
public void changeScene(JPanel scene) {
e.removeKeyDispatcher(); //You must create a method that allows you to move the event key dispatcher
t.stopAllTimers(); //You must create a method to stop all timers, or any object that is active.
t = null;
e = null;
p = null;
//If you have more active objects and work with other instances of other classes they should be "broken" or "stopped" and then match their instance to null
App.getInstance().runScene(scene);
}
//Optional...
public JLabel[][] getMat() {
return mat;
}
}
Play.java, Event.java, Timer.java (X)
public class X {
private GameScene g;
private JLabel[][] mat;
public X(GameScene g) {
this.g = g;
//I would use the instance of the class I need to access the variables I'm going to use, for example:
this.mat = g.getMat();
}
}
Hello I've just started programming and now i'm making a university project where I must get a gwtcontainer from another class and let it see in a popup window, don't know exactly how I can call it
This is a part of my code:
import com.is.lap.client.gui.Login;
public class StartRU extends TabPanel {
private static class MyPopup extends PopupPanel {
public MyPopup() {
super(true);
// Is here where i have the trouble don't know exactly how to do it
setWidget( (Widget) new Login().getLayoutData());
center();
}
}
public StartRU() {
Button LoginButton =new Button("Login");
LoginButton.setWidth("100px");
LoginButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// Instantiate the popup and show it.
new MyPopup().show();
}
});
If Login class extends Widget, you can simply
setWidget(new Login());
I am new to Apache Pivot.
I am tryng to make a simple window with menu bar.
The code I used to load the main frame is:
public class MyApp implements Application {
private Frame frame;
#Override
public void startup(Display display, Map<String, String> strings) throws Exception {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
frame = (Frame)bxmlSerializer.readObject(MyApp.class, "/gui/MainFrame.bxml");
frame.open(display);
}
#Override
public boolean shutdown(boolean b) throws Exception {
if(frame != null) {
frame.close();
}
return false;
}
#Override
public void suspend() throws Exception {
}
#Override
public void resume() throws Exception {
}
public static void main(String[] args) {
DesktopApplicationContext.main(MyApp.class, args);
}
}
The main frame BXML is like:
<root:MainFrame title="MyApp" maximized="true"
xmlns:bxml="http://pivot.apache.org/bxml"
xmlns="org.apache.pivot.wtk"
xmlns:root="com.myproject.client">
<menuBar>
<bxml:include src="wtk/menubar.bxml"/>
</menuBar>
</root:MainFrame>
The MainFrame.java is like:
public class MainFrame extends Frame implements Bindable {
public MainFrame() {
Action.getNamedActions().put("myaction1", new Action() {
#Override
public void perform(Component source) {
......
}
});
}
}
The result of this code is like the picture below:
As you can see there is an Mac window outside and a frame window inside.
My question is that how can I get rid of the system window OR get rid of the frame window so that only one window is shown?
Thank you very much.
I found a 2012 mailing list post that implies Pivot has no support for native menus, so your app will always live within the system window.
However, that mailing list post did suggest a hack using Java AWT Frame to get system menus.
First off - sorry for the wall of code but it's not too horrendous, just a framework for what I'm trying to explain. It runs without errors.
The goal
I'm making a reuseable button class for my GUI and each button object needs to have a different handler when it's clicked. I want to to assign a ClickHandler object to each new button. Then, the button would call init() on the handler, and be on its way. Unfortunately, there's a typing problem, since each handler class would have a different name.
Current progress
Right now, the handler is typed as HandlerA, but I'd like to have it handle any name, like "SettingsHandler" or "GoToTheWahWah" etc.
I've tried messing about with generic types, but since I'm new to this, and from a webdev background, there seems to be a conceptual hurdle I keep knocking over. Is this the right way to approach the problem?
The code
ReuseableButton.java is a reuseable class, the only thing that changes is the action when it's clicked:
package gui;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class ReuseableButton extends JButton implements ActionListener {
private static final long serialVersionUID = 1L;
// I want a generic type here, not just HandlerA!
private HandlerA ClickHandler;
// Assemble generic button
public ReuseableButton(Container c, String s) {
super(s);
addActionListener(this);
c.add(this);
}
// Once again, generic type, not just HandlerA!
public void SetClickHandler(HandlerA ch) {
ClickHandler = ch;
}
// Call init() from whatever class has been defined as click handler.
public void actionPerformed(ActionEvent e) {
ClickHandler.init();
}
}
Controller.java fires the frame and assembles buttons as needed (right now, only one button).
package gui;
import javax.swing.*;
import java.awt.*;
public class Controller extends JFrame {
private static final long serialVersionUID = 1L;
public Controller() {
JFrame frame = new JFrame("Handler Test GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = frame.getContentPane();
pane.setLayout(new FlowLayout());
ReuseableButton b = new ReuseableButton(pane,"Reuseable Button A");
// THE QUESTION IS HERE: Pass a generic object?
b.SetClickHandler(new HandlerA());
frame.pack();
frame.setSize(200,200);
frame.setVisible(true);
}
public static void main(String args[]) {
new Controller();
}
}
HandlerA.java is a sample of a random handler for the button click. Later, there could be HandlerB, HandlerC, etc.
package gui;
// A random handler
public class HandlerA {
public void init() {
System.out.println("Button clicked.");
}
}
Thanks very much in advance!
All of you handlers should implement an interface like Clickable or something. That way the interface specifies the existence of the init function:
public interface Clickable
{
public void init();
}
Making the HandlerA definition:
public class HandlerA implements Clickable {
public void init() {
System.out.println("Button clicked.");
}
}
I recommend to work with inheritence in this case:
public abstract class AbstractHandler {
public abstract void init();
}
Then:
public class ConcreteHandlerA extends AbstractHandler {
#Override
public void init() {
// do stuff...
}
}
Controller
public class ReuseableButton extends JButton implements ActionListener {
// I want a generic type here, not just HandlerA!
private AbstractHandler ClickHandler;
public Controller() {
//...
ReuseableButton b = new ReuseableButton(pane,"Reuseable Button A");
AbstractHandler handlerA = new ConcreteHandlerA();
b.SetClickHandler(handlerA);
// ...
}
}
Not sure if this is what you're looking for...
BTW: You can define the AbstractHandler as an interface as well, but you may want to implement some common logic here as well - shared across handlers.
You should use an interface for the handler.
public interface ClickHandler() {
void init();
}
ReuseableButton b = new ReuseableButton(pane,"Reuseable Button A");
b.SetClickHandler(object which implements the ClickHandler interface);
This is the same concept as the normal JButton. There you have the ActionListener interface and the actionPerformed method in it.
P.S. If I don't understand your question, please correct me.
I have main frame (with JFrame field) asi view, then presenter (created in view's constructor) that adds listeners to buttons and stuff. I do that like this:
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
MyWindow window = new MyWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
MyWindow invokes in it's constructor only one method - intialize - that only creates GUI fields. Finally (literally last line of it's code) it creates presenter.
Presenter should show new JDialog on certain events in main view. It has one method, that makes my GUI freeze. It looks like this:
protected double[] getParams(final Class<?> indicatorClass) {
ParametrizableDialog dialog = dialogs.get(indicatorClass); // works well
List<Double> params = new ArrayList<Double>();
dialog.setParams(params);
dialog.setModal(true);
dialog.setLocationRelativeTo(view.getFrame());
dialog.setVisible(true);
System.out.println(params); // it actually works, params are obtained from JDialog as user input
return Doubles.toArray(params); // guava
}
ParametrizableDialog is normal JDialog that implements one method interface that sets List<Double> parameters like this:
public class ParametrizableDialog extends JDialog implements Parametrizable {
protected List<Double> params;
#Override
public void setParams(final List<Double> params) {
this.params = params;
}
}
Now, does anybody know what mistake did I make and why does my GUI freeze?
Thanks!
If a GUI freezes, its generally because your are blocking the EDT. Read the section from the Swing tutorial on Concurrency for more information.
We can't tell what you are doing because your code isn't complete. For example you don't even add any components to the GUI. So who knows what you are doing in the code you left out.
For more help post your SSCCE that demonstrates the problem.