I'm making a button class that handles input and drawing by itself; the only thing that needs to be defined is the location and what happens when the button is pressed.
In this situation, would it be better to have a ButtonPressListener interface and have it as a parameter in Button's constructor, or should the Button be abstract with the abstract method pressed()?
The resulting initiation code for Button would be like the following:
new Button(x,y,new ButtonPressListener(){
#Override
protected void pressed(){
// code
}
});
or
new Button(x,y){
#Override
protected void pressed(){
// code
}
};
Also, in other similar situations, what should be considered when choosing between the two approaches?
Thanks.
I prefer the listener.
Resons:
The listener will give you more flexability, when using java8 lambdas.
You can write one class that listens to several buttons
You can write one class that listens to a button and inherits some other class
By the way: You should consider using a setter, rather then a parameter of the constructor. This will allow to create buttons without listeners - or define more than one listener. Also parameters are a little bit harder to read then setter, as parameters cannot have names in java.
If you are trying to learn from this project, you might as well do both at the same time and find out what works better for you. Wenn you found out, refactor and throw out the less liked option.
Make a default implementation of Button.pressed() that calls the function of your listener implementation if set. Supply two constructors, one that sets the listener and one that does not.
Of course that is not an option is others shall use this API.
Related
I am doing a small Java project and using MVC graphical user interfaces to write.
In this project I have dozens of button with different function.
Since I am using MVC to write, I won't use anonymous class listener. I would separate the actionlistener class in the Controller class. As I have dozens of button ,that mean I need to create dozens of actionListioner class for it??
If there is any way to simplify the code?
MVC is a structure to make easier to trace projects. It should not be a problem I think. Research please there are lots of information about it. You should use e.getSource(). Try this:
JButton b1;
JButton b2;
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
// Do something...
}
if (e.getSource() == b2) {
// Do something else...
}
}
Please look these:
One action listener, two JButtons
How to add action listener that listens to multiple buttons
http://www.java2s.com/Tutorial/Java/0260__Swing-Event/Useoneinnerclasstohandleeventsfromtwobuttons.htm
This is always a difficult thing for people to get their heads around. Instead of letting the controller worry about the actual buttons, it should be worried about what the view is allowed to do (ie the actions it can perform), which (presumably updates the model).
So, your view would actually handle the buttons events internally, but, instead of changing the state itself, it would notify the controller the a particular state has changed or action has been performed.
This communication would be managed via a series of interface contracts. This means that are particular controller is expecting to control a particular type of of view, but neither care about the actual implementation, so long as the contract between the two is maintained
With this in mind, it then means that your view can do what ever it likes and generate the "events" in anyway it likes, so long as the contract is upheld and you're not exposing parts of your view to other parts of the program which has no reason to reference it
I want to have a list of objects with different objects.
I want a super class that has an abstract getOptions() method. Then I can create subclasses of the super class and when you select a object of the subclass it will make buttons for each option of in the subclass.
I want to be able to choose the options buttons will be made for. Like if I made a subclass that represented a file it would have two options like open and edit and the program would automatically make a open and edit button, but it also needs to support other subclasses that have different options and the program would make buttons for them instead.
It don't matter if it's a button, I just wanna know how I can get a list of all options in a subclass.
Have the child class return an instance of an Action instead. The actions can be put into a menu or toolbar as needed to form JMenuItem and JButton instances.
You can create an Option class and hold just a List<Option> variable in your entity classes like file and whatever...
But maybe I did misunderstand what you really want.
If you want list of your objects' methods or properties you can use Java Reflection. However I'm not sure if this is the best solution to implement your idea.
So I'm having one super class, Block, that extends Composite and uses the UIBinder to make the layout
class Block extends Composite
I want to create two subclasses for that one, that each have different set of icons that have to be added. For example an InactiveBlock and an ActiveBlock.
My problem here is that I want the layout of both blocks (the icons, and some buttons,labels) to be made through the UIBinder aswell, and then to add that UIBinder (and it's events) to be added to the main Block.
Obviously I can't do something like
class ActiveBlock extends Block, Composite
add(initWidget(UIBinder.create(this)));
How could I accomplish this?
(ps if my question is not clear enough, please do tell so I can elaborate)
I would make it a single class with a constructor method having boolean as an input parameter (active/inactive).
So you can define all the common fields and methods in the class, like event handlers, images, etc.
And then use the constructor method to add the elements and handlers to the basic widget. Something will be added to all instances, something depending on whether it's active or not.
In this case you won't end up with duplicated code, still will have a benefit of using uibinder, and eventually your code will be simple enough for reading.
I am not skilled in GUI design. After much thought, research and experimentation I've developed several design ideas but still none that seems efficient. One design has a Session god object register a listener on every UI element when created, and every object that cares about any action registers a listener on the Session object. This seems simple and robust, as all messaging goes through a central location so it's less likely that anything is lost. It's brute force though, and seems cumbersome and inefficient.
Another design attempts to create subgroups of objects that speak to each other. This avoids the huge top-level Session and seems more efficient, but also seems error prone.
I'm trying to implement a framework for reuse where I group buttons with related purposes into toolbars and have a hierarchical approach to listening for actions performed by toolbars with relevant operations to the listener. I've gotten to this so far:
public class EditorToolBar extends JToolBar {
public static enum Command {
ZOOMIN,
ZOOMOUT,
FINER,
COARSER,
RESET
}
private ButtonCommandListener listener = new ButtonCommandListener();
public EditorToolBar() {
super("Editor Commands");
JButton button;
for (final Command cmd : Command.values()) {
button = new JButton(cmd.toString());
button.setEnabled(true);
button.setToolTipText(cmd.toString() + " Command");
button.setActionCommand(cmd.toString());
button.addActionListener(listener);
add(button);
}
}
public void addActionListener(ActionListener pNewListener) {
listener.cActionNotifier.addListener(pNewListener);
}
private class ButtonCommandListener implements ActionListener {
private NotifierImp<ActionListener> cActionNotifier = new NotifierImp<ActionListener>();
public void actionPerformed(ActionEvent pEvent) {
for (ActionListener listener : cActionNotifier) {
listener.actionPerformed(pEvent);
}
}
}
} // class EditorTooBar
and the listeners implement something like this:
public void actionPerformed(ActionEvent pEvent) {
switch (EditorToolBar.Command.valueOf(pEvent.getActionCommand())) {
case ZOOMIN:
// do something
break;
case ZOOMOUT:
// do something
break;
case FINER:
// do something
break;
case COARSER:
// do something
break;
case RESET:
// do something
break;
default:
System.out.println("Unknown EditorToolBar Command: "+pEvent.getActionCommand());
return;
}
I can enhance the instructor for the enum to also include tooltip text, images, etc. I'd like to reuse this design with just a different enum describing other toolbars. Listeners will distinguish different button actions using ActionEvent.getActionCommand() and use Command.toValue(String). I'd like this to extend to a hierarchy of classes that are listening: a superclass may implement a listener for one type of toolbar, and subclass add to that by listening for a different toolbar type. If the event is not from the toolbar the subclass is interested in, it can forward the event to the superclass. To make this work, I need a way to distinguish between one toolbar and another, but preferably without having to check for every button event possible from that toolbar. Ideally I'd like to have a toolbar factory, and just specifying an enum would be enough to fully describe a toolbar. Not being able to subclass an enum adds to the challenge here.
Is this a promising design pattern to pursue? I've not seen it anywhere else yet. Is there a better way that I should be using rather than inventing something that is inferior? A link to other options would be welcome.
Edit: Based on the answer from yash ahuja I should clarify that when I mention hierarchy I mean similar to the way that key bindings are handled (i.e. do you have a binding? No, then does your container have a binding? ... until someone consumes the key event) not the actual class hierarchy.
As a way to encapsulate functionality, consider combining JToolBar, discussed in How to Use Tool Bars, with Action, discussed in How to Use Actions. The example cited here exports a single tool bar. In contrast, the StyledEditorKit, illustrated here, exports families of Action subtypes that apply to the current selection of a text component.
The design is pretty good but if you create a hierarchy of Tool bars then, in a situation where a particular button is clicked on particular tool bar the corresponding action performed for that button may not be accurate. Also at times multiple events can be triggered.
Also there are some tool bars for which it is difficult to identify that under which super class they should belong or if they are implementing features from multiple tool bars you need multiple inheritance which Java does not supports.
Possibly a combination of Strategy Pattern and Factory Pattern could solve these issues. Please rethink on this and design your solution, sorry I don't have exact design or source for your question , I have just put my thoughts for your solution.
Regards,
Yash
When writing a graphical interface, using Java, what's the appropriate way of switching between the different windows of the application, when clicking a button for example? I.E. what are the windows supposed to be, JPanels, JFrames...? And how do all the components 'see' the 'domain controller' (the class that links the graphical package to the application logic package)?
Any guide or reference would be appreciated.
You start your application with your Controller. In the constructor of your controller, you are going to initialize the first GUI you want to open, lets say GUI_A:
private GUI_A gui_a = null;
Controller() {
gui_a = new GUI_A(this);
}
As you might notice, I called the constructor of GUI_A with one parameter: this. this is referencing the instance of the current class, so this is type of Controller. The constructor of GUI_A has to look something like this:
private Controller controller = null;
GUI_A(Controller ctrl) {
controller = ctrl;
}
This is a simple way to get the GUI known to the Controller.
The next thing you would do is displaying GUI_A:
gui_a.setVisible(true);
If you now want to handle button-clicks, you would do it like this:
First, you add the action-performed method to your button. And, as it is best practice in MVC, you don't want to do logic in your view/GUI. So you also create a corresponding method in your Controller for the action-performed, and call it from your GUI:
// Controller
GUI_A_button1_actionPerformed(ActionEvent evt) {
// Add your button logic here
}
// GUI_A
button1_actionPerformed(ActionEvent evt) {
controller.GUI_A_button1_actionPerformed(evt);
}
Usually you don't need to pass the ActionEvent-var to the Controller, as you will not need it often. More often you would read a text out of a TextField and pass it on to your Controller:
// Controller
GUI_A_button1_actionPerformed(String text) {
// Add logic for the text here
}
// GUI_A
button1_actionPerformed(ActionEvent evt) {
controller.GUI_A_button1_actionPerformed(textField1.getText());
}
If you now want to access some fields on your GUI_A from the Controller, be sure not to mark the fields as public in your GUI, but to create public methods which handle how to display the values.
The preferable way is using Actions. You can attach action to each control. When user action happens (e.g. click on button) the appropriate Action is called. Actions can delegate calls deeper into the application logic and call graphical components (JFrams, etc).
suggestion: use tabbed-panel should do this, JPanel is just a Java container, while JFrame should be the outside windows, they are different things. there should be several JPanels on top of One JFrame. your app can have multiple JFrames.
When writing a graphical interface, using Java, what's the appropriate way of switching between the different windows of the application, when clicking a button for example?
Add an ActionListener to the button. In the actionPerformed(ActionEvent) method, do what needs to be done.
I.E. what are the windows supposed to be, JPanels, JFrames...?
I would recommend making the main window a JFrame and using either a JDialog or JOptionPane for most of the other elements. Alternately, multiple GUI elements can be added into a single space in a number of ways - CardLayout, JTabbedPane, JSplitPane, JDesktopPane/JInternalFrame, ..
And how do all the components 'see' the 'domain controller' (the class that links the graphical package to the application logic package)?
One way is to pass a reference to the object between the UIs.