i am completly stuck ..
my goal is to implement a.. simple "listener" like action
but i dont know how ..
here is my code
// normaly i create an action like this
// this is JUST an example how i do this in swing
//
class la extends JFrame implements ..<someAciton>..{
JButton b = new JButton("");
add(b);
b.setAction( new Action(){
void click(){
// bla
}
});
}
my problem is, i want to create this funnctionality in android in general in java
currently i have 3 classes and 1 interface
// the interface, it holds my action, wich should be performed
//
//
public interface GameActionInterface extends EventListener {
public void onTouched( MotionEvent event );
}
// this is the class whichs runs the action
//
//
public class GameActionListener {
ArrayList<GameLayoutBase>touchedListener = new ArrayList();
public void addTouchListener(GameLayoutBase obj){
touchedListener.add(obj);
}
public void onTouched( MotionEvent event){
for( GameLayoutBase elem : touchedListener ){
elem.onTouched(event);
}
}
}
// this class should to the action later
//
//
public class GameLayoutElement extends GameLayoutBase {
public GameLayoutElement(String ID) {
super(ID);
}
}
// my main class
//
//
gameEventListener = new GameActionListener();
// creating the obj
layout_Element_Player[0] = new GameLayoutElement("Builder_countA");
//
// and here is the PROBLEM - i want to overwrite the current function with my "own" code
gameEventListener.addTouchListener(layout_Element_Player[0]);
// adding the element to the listener
//
//
layout_Element_Player[0].onTouched( new GameActionInterface(){
} );
i dont know how to solve thge problem :(
here is the answer .. its quite simple .. my mind went blank ..
// handels the button
public class TestButtonVerwaltung {
ArrayList <TestButton>liste = new ArrayList();
public void add( TestButton object){
liste.add(object);
}
public void doAction( MotionEvent event){
for( TestButton elem : liste ){
elem.on(event);
}
}
}
// new button
public class TestButton {
View.OnTouchListener it;
public void addOnTouched( View.OnTouchListener doit ){
it = doit;
}
public void on(MotionEvent event){
it.onTouch(null, event);
}
}
// in the main
TestButton testBt = new TestButton();
TestButtonVerwaltung tBV = new TestButtonVerwaltung();
tBV.add(testBt);
//the trigger function
#Override
public boolean onTouchEvent(MotionEvent event) {
tBV.doAction(event);
}
Related
I defined a custom FieldEditorPreferencePage. In createFieldEditors method I construct a simple interface with a custom FieldEditor that holds button that loads a file. When a user loads the file the interface region (where the button stands) need to change and show other specific gui. How to invalidate the FieldEditorPreferencePage? I used the layout() method of the parent composite but nothing happens. What am I doing wrong here?
public class MyPage extends FieldEditorPreferencePage {
...
private Composite fieldEditorParent;
private boolean fileLoaded = false;
#Override
protected void createFieldEditors() {
fieldEditorParent = this.getFieldEditorParent();
MyFieldEditor compositeFieldEditor = new MyFieldEditor(fieldEditorParent) {
if(fileLoaded) {
//draw file content
} else {
Button chooseButton = new Button(buttonsComposite, SWT.NONE);
chooseButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
//choose file
fileLoaded = true;
//invalidate page <-- THIS DOES NOT WORK!
fieldEditorParent.layout(true, true);
}
}
}
}
}
So I'm trying to pass the current class inside a constructor of an actionlistner
something like this:
public ActionListener createTaskListener() {
return new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
CreateTask ct = new CreateTask();
CreateTaskController ctc = new CreateTaskController(ct, mod.getAssessments(), this);
// but it says anonymous actionlistener
ctc.loadDataToTaskView();
ct.setVisible(true);
}
};
}
What is the general approach for a problem like this? Or is this just shoddy code?
this will point to the anonymous instance of the action listener. If you want to pass the this pointer of the enclosing class, use <enclosingClassName>.this.
e.g.:
class MyClass {
public ActionListener createTaskListener() {
return new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
...
CreateTaskController ctc =
new CreateTaskController(ct, mod.getAssessments(), MyClass.this); // <-
...
}
};
}
}
As a side note. ActionListener is a functional interface. So you could simplify your code with a lambda expression:
class MyClass {
public ActionListener createTaskListener() {
return ae -> {
CreateTask ct = new CreateTask();
CreateTaskController ctc =
new CreateTaskController(ct, mod.getAssessments(), MyClass.this);
ctc.loadDataToTaskView();
ct.setVisible(true);
};
}
}
this within an inner class refers to the inner class instance. To refer to the enclosing class instance, you can use OuterclassName.this.
For example
public ActionListener createTaskListener() {
return new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
CreateTask ct = new CreateTask();
CreateTaskController ctc = new CreateTaskController(ct, mod.getAssessments(), YourClassName.this);
// but it says anonymous actionlistener
ctc.loadDataToTaskView();
ct.setVisible(true);
}
};
}
I want to create a popup (implemented as a DialogBox or other similar component) which i should be able to reuse in multiple pages or forms. I want the DialogBox to be able to return a value to the "opener".
I am thinking i.e. on a DialogBox that shows a table (obtained via RPC). That DialogBox can be used in several different pages. When the user selects a row, an object is "passed back to the page" (for example, calling a method on it), so it can write it to a form field, or do whatever with it. The called doesn't know anything about the logic inside de DialogBox, only knows how to deal with the returning type.
A good example of what i'm intending to do could be a DatePicker that returns a java.util.Date.
Have you done something similiar?
I appreciate your help.
Thanks!
David
It's really easy. You should first create an interface that will be implemented by all the pages opening you DialogBox :
public interface DialogBoxOpener {
void dialogBoxValidated (Date selectedDate);
void dialogBoxCancelled ();
}
Then, create your DialogBox, and take a DialogBoxOpener as parameter to your showDialogBox method :
public class MyDialogBox extends DialogBox {
private DialogBoxOpener opener = null;
private final Button cancelButton = new Button("Cancel");
private final Button validButton = new Button("Ok");
private final DateBox myDateBox = new DateBox();
public MyDialogBox () {
cancelButton.addClickHandler(new ClickHandler () {
#Override
public void onClick(final ClickEvent event) {
hide();
if (opener!=null)
opener.dialogBoxCancelled();
}
});
validButton.addClickHandler(new ClickHandler () {
#Override
public void onClick(final ClickEvent event) {
hide();
if (opener!=null)
opener.dialogBoxValidated(myDateBox.getValue());
}
});
// TODO : create your DialogBox
}
public void showDialogBox (final DialogBoxOpener opener) {
this.opener = opener;
// Show the DialogBox
center ();
}
}
And now, you can show your DialogBox from your page :
public class MyPage implements DialogBoxOpener {
private MyDialogBox myDialogBox = getMyDialogBox();
private void openDialogBox () {
myDialogBox.showDialogBox(this);
}
public void dialogBoxValidated (Date selectedDate) {
// TODO : Do something with the date
}
public void dialogBoxCancelled () {
// TODO : Do something
}
}
I have a problem with ClickHandler in my project using GWT.
In the title of dialog box I want to insert a new button.
I created a new insert method: addToTitle(...).
I added ClickHandler to the button
Problem: click event by button doesn't fire. Why?
Here is my code:
DialogBox dialog = new DialogBox();
Button button = new Button("A new Button");
button.addClickHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
Window.alert("yuhuhuhu");
}
});
dialog.addToTitle(button);
code (extracted from the comments section) :
public class PlentyDialogWindow extends DialogBox {
private FlowPanel captionPanel = new FlowPanel();
public Widget closeWidget = null;
private boolean closeOnEscKey = false;
private FlowPanel titleContentWrapper = new FlowPanel();
public PlentyDialogWindow(boolean isModal) {
super( false, isModal);
this.addStyleName("DialogBox");
this.getElement().setId("DialogBoxId");
this.setAnimationEnabled(true);
this.closeWidget = generateCloseButton();
}
public void setCaption( String txt,Widget w) {
captionPanel.setWidth("100%");
this.addCaption(txt);
this.titleContentWrapper.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
captionPanel.add(this.titleContentWrapper);
FlowPanel widgetWrapper = new FlowPanel();
widgetWrapper.add(w);
widgetWrapper.addStyleName("PlentyPopupCloseIconWrapper");
captionPanel.add(widgetWrapper);
captionPanel.addStyleName("Caption");
Element td = getCellElement(0,1);
td.setInnerHTML("");
td.appendChild(captionPanel.getElement());
}
/** * * #param w */ public void addToTitle(Widget w) {
this.titleContentWrapper.add(w);
}
}
If your only problem is ClickHandler not being called try using addDOMHandler instead of addClickHandler
yourWidget.addDomHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
}
},ClickEvent.getType());
The solution is a bit tricky.
public class PlentyDialogWindow extends DialogBox {
/*
* Create custom inner class extending `FlowPanel`. You need it only
* to make `onAttach` and `onDetach` methods be visible to wrapping
* class (e.g. your `PlentyDialogWindow` class).
*/
static class MyCaptionPanel extends FlowPanel {
#Override
protected void onAttach() {
super.onAttach();
}
#Override
protected void onDetach() {
super.onDetach();
}
}
/*
* `PlentyDialogWindow`'s field `captionPanel` will be an instance of
* this class.
*/
private MyCaptionPanel captionPanel = new MyCaptionPanel();
/*
* ... leave the rest of your class untouched ...
*/
/*
* Finally, overwrite `PlentyDialogWindow`'s `onAttach` and `onDetach`
* methods to invoke `captionPanel`'s corresponding methods:
*/
#Override
protected void onAttach() {
super.onAttach();
captionPanel.onAttach();
}
#Override
protected void onDetach() {
super.onDetach();
captionPanel.onDetach();
}
}
That's all.
My use case is that a List<String> is passed to a Jpanel and for each String in the List, the JPanel renders a UI component. This UI component consists of 3 buttons and my current code for my given use case is as follows. -- The code for the 'UI component' follows --
public class MacroEditorEntity implements ActionListener {
private String macro;
private JButton upButton;
private JButton downButton;
private JButton MacroDetailsButton;
public MacroEditorEntity(String macro) {
this.macro = macro;
upButton = new JButton("Up");
downButton = new JButton("Down");
MacroDetailsButton = new JButton(macro);
upButton.addActionListener(this);
downButton.addActionListener(this);
MacroDetailsButton.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent evt) {
if(evt.getSource().equals(MacroDetailsButton))
{
System.out.println(macro);
}
}
public JButton GetUpButton()
{
return upButton;
}
public JButton GetDownButton()
{
return downButton;
}
public JButton getMacroDetailsButton()
{
return MacroDetailsButton;
}
}
The code for my Panel is as follows --
public class MacroEditor extends JPanel implements PropertyChangeListener {
private static final long serialVersionUID = 1L;
private List<String> stringlist;
public MacroEditor(List<String> list) {
this.stringlist = list;
setupComponents();
validate();
setVisible(true);
}
public void setupComponents()
{
Box allButtons = Box.createVerticalBox();
for(String string : stringlist)
{
MacroEditorEntity entry = new MacroEditorEntity(string);
Box entryBox = Box.createHorizontalBox();
entryBox.add(entry.GetUpButton());
entryBox.add(Box.createHorizontalStrut(15));
entryBox.add(entry.getMacroDetailsButton());
entryBox.add(Box.createHorizontalStrut(15));
entryBox.add(entry.GetDownButton());
allButtons.add(entryBox);
}
add(allButtons);
}
#Override
public void propertyChange(PropertyChangeEvent arg0) {
revalidate();
repaint();
}
}
The code works fine for all Strings in the passed List. I want my Panel to pick up any change that may happen to the List like additions or deletions and add/remove relevant corresponding UI components accordingly. I think this can be done by using PropertyChangeListener but have not been able to account for that in my code.
Any ideas or suggestions on how i can make my Panel render/rerender stuff as soon as there are changes to the List would be of help.
What you need here is an observable collection. This should do it: http://commons.apache.org/dormant/events/apidocs/org/apache/commons/events/observable/ObservableCollection.html
Edit:
Here's the code snippet you requested:
public class ObservableListExample implements StandardPostModificationListener,
StandardPreModificationListener {
public static void main(String[] args) {
new ObservableListExample();
}
public ObservableListExample() {
ObservableList list = ObservableList.decorate(new ArrayList<>(),
new StandardModificationHandler());
list.getHandler().addPostModificationListener(this);
list.getHandler().addPreModificationListener(this);
//....
}
#Override
public void modificationOccurring(StandardPreModificationEvent event) {
// before modification
Collection changeCollection = event.getChangeCollection();
if (event.isTypeAdd()) {
// changeCollection contains added elements
} else if (event.isTypeReduce()) {
// changeCollection contains removed elements
}
}
#Override
public void modificationOccurred(StandardPostModificationEvent event) {
// after modification
Collection changeCollection = event.getChangeCollection();
if (event.isTypeAdd()) {
// changeCollection contains added elements
} else if (event.isTypeReduce()) {
// changeCollection contains removed elements
}
}
}
By the way: Another concept that helps to bind buisness objects to your GUI and react to modifications (bidirectionally) is Data Binding. Have a look at this, a Data Binding Library commonly used with Swing.