this is my first spring application (maven project) which is supposed to allow users to upload and validate a file. At the moment I only have the default class called MyUI.java which contains all I need, here is an extract:
EDITED CODE:
FileUploader.java
public class FileUploader extends AbstractJavaScriptComponent {
public void callScript(){//as usual, it needs a method!!
JavaScript.getCurrent().execute(""
+"jsInit();"
+"");
}
And changes to the MyUI class:
`final FileUploader fileUploader = new FileUploader();//has to be final apparently
final Button button = new Button("Open popup");
button.addClickListener(new Button.ClickListener(){
#Override
public void buttonClick(ClickEvent event){
fileUploader.callScript();
}
});`
I need to move the js call to a new java class in a separate file, so I created a new class which now sits in its own file and that will extend AbstractJavaScriptComponent, my question is, what imports do I need for this class, all the ones that are in the previous class except for the UI or including those? Literally this class will only have the js call for now (there will be more stuff later)?
Also, to make use of this class presumably I will have to run As --> maven install again? And in general, what should I do?
cheers
This is a simple case of refactoring to extract a method and add a class.
You want to replace this
final Button button = new Button("Open popup");
JavaScript.getCurrent().execute("jsInit();");
With something like this
final Button button = new Button("Open popup");
JavaScriptCaller jsCaller = new JavaScriptCaller(JavaScript.getCurrent());
jsCaller.jsInit();
So, you can define a class like so
public class JavaScriptCaller extends AbstractJavaScriptComponent {
final JavaScript js;
public JavaScriptCaller(JavaScript js) {
this.js = js;
}
public void jsInit() {
this.js.execute("jsInit();")
}
}
The reason I added the parameter is so you don't need to keep calling the Javascript.getCurrent() since you only need one instance of it.
Related
To begin with I'm in this just a few days so I am sorry if this is a silly question, I did my search but I didn't find what I was looking for.
Simply said, I've got a class like this:
public class logout extends JButton {
private static final long serialVersionUID = -4813329911065574369L;
public static JButton logout = new JButton("Izloguj se");
public logout()
{
//parameters like font, foreground etc
}
And when I try to call it in another class, like this:
ctrl.add(prikaz.logout.logout);
I get an old plain button with text I defined in class but none of the parameters I defined for it.
I know I can add the button with its settings if I do something like:
JPanel lgtBtn = new logout();
But I would like to do it directly with add.
You define the logout button with:
public static JButton logout = new JButton("Izloguj se");
This creates a new JButton with the specified text. But then the class you are in also extends JButton, and it is set up in the constructor. So you have two JButtons, but you only ever reference the one that is not set up. I would just get rid of the line of code above, and reference the button as prikaz.logout (not prikaz.logout.logout).
I currently have all my action listeners declared under my constructor, but I'm starting to get a lot of them building up. Is it possible to create a new classes (via the default package window) and have them all there separately?
This seems obvious to me, I have tried this and I get no errors, but my application wont load when I do, it says its open but theres nothing there.
Here is a link to my code that is compilable.. I have commented out anything that uses other classes (there isn't much), if I have missed any just comment them out.
https://shrib.com/Tum8kjgH?v=nc
Thanks!
The most simple solution is to declare your listeners each in their own class. For example, for some button:
public class SomeButtonActionListener implements ActionListener{
private InternalFrame iFrame;
public SomeActionListener(InternalFrame iFrame){
this.iFrame = iFrame;
}
public void actionPerformed(ActionEvent ae) {
//TODO
//Example: iFrame.getSomeButton().doSomething();
}
}
Note that in this way, you need to expose getter methods for all swing components you need to access from your listeners (an alternative is to send the specific components needed as arguments to the listener when constructor is called).
In your InternalFrame you can add the listeners as:
someButton.addActionListener(new SomeButtonActionListener(this));
Also you can put all your listeners in a specific package like yourapp.listeners.
EDIT
A more specific example:
public class AddRoomListener implements ActionListener{
private InternalFrame iFrame;
public AddRoomListener(InternalFrame iFrame){
this.iFrame = iFrame;
}
public void actionPerformed(ActionEvent event) {
iFrame.getIntFrame2().setVisible(true);
iFrame.getIntFrame2().toFront();
}
}
In this case you need to declare the getIntFrame2() getter in the InternalFrame class.
I am using GWT and would like to call the Popup.Hide() method in the Library class MenuBar but it is private and the Object is private too...
so what is the best way to get the method:
If I create a complete new class which inherits from MenuBar, will not work I have to create 10 other classes which depend on the MenuBar, for example MenuItem, since MenuItems also hold private static variables, which seems too involved.
unzip the .jar and change the method to public.
another way?
there's no Hide() uppercase method in java, did you read the javadoc? hide() is also a lowercase method. Do you use eclipse with the Google plugin?
Button b1 = new Button("Click me to show popup");
b1.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// Instantiate the popup and show it.
new MyPopup().show();
}
});
http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/PopupPanel.html
I have a dude about how to implement Actions in Swing.
My idea is create a Class for each action of my application extending AbstractAction so I can use in many components that must have the same behavior. So I finaly have something as:
public class ActionExample extends AbstractAction {
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Do something");
}
}
Well, now when I want to use it I have three options in my mind:
public void makeUI1() {
JButton btn = new JButton(new ActionExample("Do it"));
JMenuItem mi = new JMenuItem(new ActionExample("Do it"));
}
public void makeUI2() {
Action a = new ActionExample("Do it");
JButton btn = new JButton(a);
JMenuItem mi = new JMenuItem(a);
}
Or use it as a singleton (also changing ActionExample):
public void makeUI2() {
JButton btn = new JButton(ActionExample.getInstance());
JMenuItem mi = new JMenuItem(ActionExample.getInstance());
}
public class ActionExample extends AbstractAction {
private static final ActionExample INSTANCE = new ActionExample("Do it");
public static Action getInstance() {
return INSTANCE;
}
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Do something");
}
}
My first opinion was make it through singleton instance but I see in oracle tutorial that it make a new instance before setting it into components and in the I also see that many code create new instance for each component so I don't know what it's better and why.
Is preferred one method to be used over the other?
The multi instance action allows you to save data in the moment of the action for further use.
Imagine you want to add undo/redo functionality. You need to save what actions have been done for every action.
Singleton does not provide any advantage in this case.
I think the best thing to do would be to use the MVC pattern. Your AbstractAction class is a controller. It's responsible for extracting the information necessary for the model (ie: business logic) to use. The model/business logic is the part you reuse, but the controller may differ greatly even if it uses the same business logic.
For example, you may have a JComponent that you need to add a KeyListener to. Suddenly, your pre-made AbstractAction has become worthless because it can't be used in this situation. But, as long as you reuse all the business logic code in your KeyListener that you used in your AbstractAction, you're doing things right.
I'm quite new to interface design and struggling to figure out what the best way to handle events is. In the straight forward case of the handler and the (in this case) buttons causing the event being in the same class, that's fine, I get it. The handler can see the buttons so that it can say:
if (event.getSource() == myButton)
and also, the handler is in the same class so it can add tabs to an object local to that class or similar.
Problem: I don't know how I should be dealing with the case when the handlers and event generators are in different classes.
e.g.
From my main layout class I create and show a custom dialog. That dialog is implemented in its own class. Ideally dialog would use the handler from the main layout class (it implements ClickHandler), which would be fine, but my application has a few different ClickEvents. I distinguish between them as above by checking the source. In this case the buttons are in the dialog class though, so I can't simply say:
if (event.getSource() == myDialogbutton)
as myDialogButton is not in scope.
Any hints for how this should work would be appreciated.
D
Perhaps I can help you with my solution ...
I inherited ClickHandler to an own class which is generic. You can give the ClickHandler any kind of object you want and will be able to access it from the method within.
Example:
import com.google.gwt.event.dom.client.ClickHandler;
public abstract class ClickHandlerData<T> implements ClickHandler {
private T data;
public ClickHandlerData(T data)
{
this.data = data;
}
public T getData()
{
return data;
}
public void setData(T data)
{
this.data = data;
}
}
Now, in case of a button:
Button btn = new Button("click me");
btn.addClickHandler(new ClickHandlerData<Button>(btn)) {
public void onClick(ClickEvent event) {
Button btn = getData();
...
}
}
I use this class to pass parameters like Integers or something else to the ClickHandler. For instance:
for (int i=0;i<10;i++)
{
Button btn = new Button("click me");
btn.addClickHandler(new ClickHandlerData<Integer>(i)) {
public void onClick(ClickEvent event) {
Window.alert("you klicked button "+getData());
...
}
}
}
I also do the same for AsyncCallbacks, for Commands, for everything else I need to pass data to.
Hope this helped you a bit.
It appears to me that you are trying to use one listener for multiple buttons, unless several of the buttons have the same function they should have different listeners.
In general you should try to have one listener per function, instead of one listener per "event generator".
If you have for example a logout button, it may have a listener from the LoginStatusWidget (displaying who the client is logged in as) and a listener from an object responsable of notefying the server of the logout.
It will serve to seperate the components from each other.
At first i recommend you to try to collect your Buttons and their ClickHandlers in the same class, but if in your case it is not possible, I have a suggestion to you:
When you are creating your Button you can add some information to them:
Button button = new Button("submit");
button.setLayoutData(someObj);
And then after firing event you can get your Button from event in your ClickHandler and find out which button it is :
Button button = (Button) event.getSource();
MetaData someObj = (MetaData) button.getLayoutData();
Try creating a new listener for each anonymous or serial widget e.g. button in a FlexTable. That way their life cycles are connected and they only refer to each other.
Extend the widget
Give it an id and add it to the constructor [make sure the id is one of a kind]
Implement the listener class.
create a new instance of the listener each time you create an item of the same kind.
I'm guessing there are specific objects connected to the widgets. If so keep a HashMap.
May the force be with you
Can't you just do:
final Button source= new Button("My Button");
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
doSomething(source);
}
}
Note the button instance has to be marked final.