I'm trying to create a menu screen, and I want to be able to create it, and any further permutations of it dynamically. I've created a MenuItem helper class to handle the menu items that show up, and it reads the name, image, and set the next state (something that is handled later). What I want to know is, how can I create the specific following Screens (they'll all be some subclass of my Screen class)?
What is the most efficient method to pass specific objects into the menuItems? Do I need to pre-create each possible Screen and then just read back in the serialized form of it, or can I create them dynamically. I'd hoped to be able to do something as simple as reading in a literal string "new SubClass(...)" and act off that, but I don't know how to go about that. Any other suggestions would be great!
If I understand correctly, what you want is a mechanism that reads a String command from a text file, and based on this command, displays a screen.
So, extract the interface of the "display screen" command into an interface. For example:
public interface ScreenDisplayer {
void displayScreen(Screen mainScreen);
}
Then build a Map<String, ScreenDisplayer>:
map.put("screen1", new ScreenDisplayer() {
#Override
void displayScreen(Screen mainScreen) {
// TODO display screen 1
});
// same for all the other commands
And when a "menu item" is clicked, get the DisplayScreen from the map and call it:
String command = selectedMenuItem.getCommand();
ScreenDisplayer displayer = map.get(command);
displayer.displayScreen(mainScreen);
Related
I am making a library where an application can use it to capture a selection of a screen and convert it to an image, like Gyazo.
This library is not the application itself, but only the tool that returns the File or BufferedImage object to the application.
I want the application to be simple as this:
Bootstrap b = new Boostrap(new GifCapturer());
b.beginCapture(); // user selects an area
File file = b.getFile();
But how can I make the application wait till the library returns the object? as you see the beginCapture method should activate the JFrame where the user will select an area to capture.
Do I need to sleep the thread? or use listeners design?
The beginCapture method starts a jframe window, where the user is able to select an area of the screen. Once selected, the library will convert the selected area to an object and set it as a local variable. So when you will use getFile it ill return the captured image. But the thing is, i need to make sure that the image was selected before getFile call gets executed, and wait instead but im not sure how.
Sorry if the question is not detailed, im on phone.
Please let me know if you need more information.
Implement a listener, that is invoked as soon the selection is ready. Put your File file = b.getFile(); code into the listener.
The code of your JFrame would be necessary to give a more detailed answer.
I have decided to use a Listener with a own built listener class, and interface.
Create an interface which you will use to get the data, or that will get know when the listener gets called, like this in my case:
public static void main(String[] args) throws AWTException {
Bootstrap b = new Bootstrap(new GifCapturer());
b.beginCapture(new ScreenCaptureCallback() {
#Override
public void captureEnded(File file) {
System.out.println("done!");
}
});
}
I have a GXT 3 app and I'm trying to use a ToggleButtonCell to allow the user to modify a Boolean value.
Here's the code for the data:
public class InspectionListGridData {
private Boolean posted;
public InspectionListGridData(InspectionListGridData dataToCopy) {
setPosted(dataToCopy.getPosted());
}
public Boolean getPosted() {
return posted;
}
public void setPosted(Boolean posted) {
this.posted = posted;
}
}
For the grid to access the data, I provide this property access interface:
interface ListProperties extends PropertyAccess<InspectionListGridData> {
ValueProvider<InspectionListGridData, Boolean> posted();
}
The Grid & column config are declared like this:
final ListProperties properties = GWT.create(ListProperties.class);
final List<ColumnConfig<InspectionListGridData,?>> columnConfigList = new ArrayList<ColumnConfig<InspectionListGridData,?>>();
final ListStore<InspectionListGridData> store = new ListStore<InspectionListGridData>(
new ModelKeyProvider<InspectionListGridData>() {
#Override
public String getKey(InspectionListGridData item) {
return item.getInspectionDocumentId().toString();
}
}
});
final ColumnConfig<InspectionListGridData, Boolean> postedColumnConfig = new ColumnConfig<InspectionListGridData, Boolean>(properties.posted(), 5, "Posted");
ToggleButtonCell postedButtonCell = new ToggleButtonCell();
postedButtonCell.setText("posted");
postedButtonCell.setIcon(SafedoorPM.localizedResources.postedIcon());
postedButtonCell.setIconAlign(IconAlign.TOP);
postedColumnConfig.setCell(postedButtonCell);
postedColumnConfig.setSortable(false);
columnConfigList.add(postedColumnConfig);
Grid<InspectionListGridData> inspectionListGrid = new Grid<InspectionListGridData>(store, columnModel);
When I load this screen, the buttons do not initialize to the corresponding state indicated by the data. [EDIT: the failed loading of initial values was due to a different bug. Once I fixed that the initial values loaded correctly]
Once the screen is loaded, if I click a button it changes state just fine but the store doesn't get updated. I set breakpoint on the InspectionListGridData.setPosted() method, it is not called when I click on the button.
Can anyone see what I'm doing wrong? Or am I just wrong in thinking this is supposed to just work? I thought that was the point of the ValueProvider interfaces.
Bonus extra weirdness, the grid displays the red triangle in the corner to indicate that the cell is dirty when it is clicked and button does display properly when clicked i.e. it stays down or up. It just doesn't seem to read or update the data store.
Two questions here, at first I only keyed off of the first one (which I still can't answer, but more info might help), but the second is very clear.
When I load this screen, the buttons do not initialize to the corresponding state indicated by the data.
This is confusing, and contradicted by a quick sample I put together, as I indicated in my comment It could be that you are changing the data after drawing the grid and not informing the store or grid that the data has changed, but if you are building the data with both true and false values, the grid should be displaying with both true and false values.
I set breakpoint on the InspectionListGridData.setPosted() method, it is not called when I click on the button.
By default, this is expected while store.isAutoCommmit() is true, which is the default value. This tells the store that it should queue up changes rather than applying them directly to the objects in the store. These changed values are marked in the UI with the red triangle you noticed, and other code can check for changed values through the Store.getRecord(M) method or Store.getModifiedRecords() calls. Calling store.commitChanges() will apply all of them to the underlying models, or you can commit to specific models with Record.commit(). You can also reject changes with Store.rejectChanges() or Record.revert().
When this is turned off, the setPosted method should be called by clicking the button. No change tracking can occur, so no dirty flag will be set, either visually or in the store's records.
If you change an object that is already rendered, you have two (main) choices - you can modify the object directly via its setters and inform the store, or you can use the store's record objects. If autocommit is false and you invoke store.getRecord(object).addChange(properties.posted(), true), then instead of creating a new change to be committed, this will call setPosted(true), so these methods are effectively the same when autocommit is false. If you directly call a setter, be sure to inform the store that the object has changed via store.update.
I'm new to Java programming and am facing a (most likely) easy problem that I don't seem to be able to get across nor understand.
I have three different java files, one where I create an interface (SimulatorGui.java), other where I am creating a panel to use on the jTabbedPanel created in the interface (CollisionPanel.java - CollisionPanel class) and a third one, where I run a code that will create the output needed (Collision.java - Colision class).
In the Collision.java main method, I am doing the following:
public static void main (String[] args) {
//<editor-fold defaultstate="collapsed" desc="Simulation start procedures">
Tally statC = new Tally ("Statistics on collisions");
Collision col = new Collision (100, 50);
col.simulateRuns (100, new MRG32k3a(), statC);
//</editor-fold>
new SimulatorGUI().setVisible(true);
CollisionPanel update = new CollisionPanel();
update.updatepanel();
The first block, will create the desired output. I then want to send that output to the updatepanel! I am not passing any arguments to the method as I am still trying to debug this. updatepanel method is created in the file CollisionPanel as following:
public void updatepanel(){
System.out.println ("debug");
jTextArea1.setText("update\n");
}
What happens then is that when I run the Collision.java file it will output the "debug" text but won't set the text to the jTextArea1 (append doesn't work aswell). I then created a button to try and do so and in that case it works. In CollisionPanel.java:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
updatepanel();
}
This does the trick! I've searched and tried different things but can't seem to understand why this won't work.
Thanks in advance for your help, hope I've made the problem clear!
Okay I think I've eventually got the problem, and it is because of the IDE, you see in your main method you initiate a new CollisionPanel, which is wrong, netbeans has already added and initiated that panel in the SimulatorGUI, so now what you need to do is add a get method in the SimulatorGUI to get the initiated panel, then call the update method on that panel.
So add this to SimulatorGUI:
public CollisionPanel getCollisionPanel1() {
return collisionPanel1;
}
replace your old updatePanel() method with:
void updatepanel(String str) {
System.out.println ("debug");
jTextArea1.setText(str);
// jTextArea1.revalidate();
jLabel1.setText("test");
}
after that change your main too look like this:
SimulatorGUI simulatorGUI = new SimulatorGUI();
simulatorGUI.setVisible(true);
CollisionPanel cp=simulatorGUI.getCollisionPanel1();
cp.updatepanel("Hi");
and dont forget to remove the old updatePanel() method call from your CollisionPanel constructor, because now you can simply call cp.updatePanel("text here"); in your SimulatorGUI class instead of calling it only in the constructor.
I hope this is easy to grasp, if you're unsure let me know
Where do you add your CollisionPanel to the main GUI? I fear that this is your problem, and that you need to do this for your code to work. In fact where do any of your three classes get a reference to the others? For different classes to work in a program, there must be some communication between them. Understand that if you create a CollisionPanel object inside the GUI, and create another CollisionPanel object inside of the main method, calling a method on one object will have no effect on the other since they are two completely distinct entities.
For example, this code:
new SimulatorGUI().setVisible(true);
CollisionPanel update = new CollisionPanel();
update.updatepanel();
It appears that you are in fact calling updatePanel() on a CollisionPanel, but it's not on any CollisionPanel that is visualized in your GUI.
Consider giving SimulatorGUI a method that allows one to pass the CollisionPanel into it so that it can use it. This may in fact be a constructor parameter:
CollisionPanel update = new CollisionPanel();
SimulatorGUI simulatorGUI = new SimulatorGUI(update);
update.updatePanel();
Meaning SimulatorGUI's constructor would have to look something like:
public SimulatorGUI(CollisionPanel update) {
this.update = update;
// add update to GUI somewhere
}
There are three different levels when developping a GUI:
The view: the graphical component
The Model: the code that you run
The controller: checks if are update on the model in order to refresh the view.
So When you first start your program, the view will have the value assigned in the code; for instance say you created your JTextArea with the initial value type here. The view will show the JTextArea with the text type here.
When a change is made to the model, the view is not aware of it, it is job of the controller to check for update on the model and then refresh the view.
So this:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
updatepanel();
}
Will generate an event that say a property has been modify. So the controller will update the view.
Other than that, the change will not appear on the view.
Hope this helps..
I am trying to create a console that would work as a shell for a custom programming language. It would be very similar to the pydev interactive console.
Currently, my RCP uses the basic TextConsole and is connected to the shell via pipes so it just displays whatever the shell displays and if the user enters anything in the RCP console, the same is written in the shell.
I want to be able to do a bit more such as move the caret position, add events for up and down arrow keys etc. I believe to do that I need to add a StyledText widget to the console which is done via the ConsoleViewer.
So my question is, that is there any way for me to either override the TextConsole's ConsoleViewer or if I were to extend TextConsole and create my own, then how do I link it with the launch configuration (the one that connects the shell via pipes)?
Also, to get the current default console I use DebugUITools.getConsole(process).
I'm sorry if I haven't put all the information needed; it is a bit difficult to explain. I am happy to add more information.
An idea...
From what I understand I can create a TextConsolePage from the TextConsole using createPage(ConsoleView). Once I have the page I can set the viewer via setViewer(viewer). Here I thought if I create my own viewer (which will have the appropriate stylewidget) then that could be a lead. The only problem is that the viewer needs a Composite and I can't seem to figure out where to get that from.
Why don't you just follow what PyDev does (if you're able to cope with the EPL license)?
The relevant code may be found at:
https://github.com/aptana/Pydev/tree/ad4fd3512c899b73264e4ee981be0c4b69ed5b27/plugins/org.python.pydev/src_dltk_console
https://github.com/aptana/Pydev/tree/ad4fd3512c899b73264e4ee981be0c4b69ed5b27/plugins/org.python.pydev.debug/src_console
So I thought I would answer this myself as I was finally able to accomplish the console. It still is a working prototype but I guess as you keep adding things, you can clean up the code more and more. For my current purposes this is how it worked.
If you want the short version, then I basically mimicked the ProcessConsole provided by Eclipse as that is what I needed: a console in which I can connect a process but since the ProcessConsole is internal, I like to avoid extending those classes.
Following is an outline of the classes I used to achieve interaction with my console. I am not going to give the pretext as to where MyConsole was created. Basically, instead of using DebugUITools.getConsole(myProcess), I used my own myProcess.getConsole() method. MyProcess extends RuntimeProcess.
class MyConsole extends IOConsole {
private IOConsoleInputStream fInput;
private IOConsoleOutputStream fOutput;
private IStreamsProxy fStreamsProxy;
private ConsoleHistory history;
//This is to remember the caret position after the prompt
private int caretAtPrompt;
/* in the console so when you need to replace the command on up and down
* arrow keys you have the position.
* I just did a caretAtPrompt += String.Length wherever string was
* appended to the console. Mainly in the streamlistener and
* InputJob unless you specifically output something to the output
* stream.
*/
//In the constructor you assign all the above fields. Below are some
//to point out.
//fInput = getInputStream();
// fStreamsProxy = process.getStreamsProxy();
// fOutput = newOutputStream();
//We must override the following method to get access to the caret
#Override
public IPageBookViewPage createPage(IConsoleView view) {
return new MyConsolePage(this, view);
}
//After this I followed the ProcessConsole and added the
//InputJob and StreamListener
//defined in there.
}
class MyConsolePage extends TextConsolePage {
//Not much in this class, just override the createViewer
// to return MyConsoleViewer
}
class MyConsoleViewer extends TextConsoleViewer {
//This is the most important class and most of the work is done here
//Again I basically copied everything from IOConsoleViewer and then
//updated whatever I needed
//I added a VerifyKeyListener for the up and down arrow
//keys for the console history
MyConsoleViewer (Composite parent, MyConsole console) {
//I have omitted a lot of code as it was too much to put up,
//just highlighted a few
getTextWidget().addVerifyKeyListener(new MyKeyChecker());
}
class MyKeyChecker implements VerifyKeyListener {...}
}
This is the code for ProcessConsole.
This is the code for IOConsoleViewer.
The ConsoleHistory class I created just had a doubly linked string list to save all the commands the user entered. Quite a simple class to create.
Once you look at the Eclipse classes (ProcessConsole and IOConsoleViewer) it is actually all quite self explanatory. I haven't put in much code here because there is quite a bit. But hopefully this gives some direction as I was completely lost when I started.
I am happy to answer questions though and add more specific code if anyone asks.
I am creating a java app.
I have one class q2a2 which is a jpanel whose design is shown as follows: -img-
Suppose if an item is selected from the combo-box and "Create Account" button is clicked. One tab is added to the jTabbedPane. every item has a common tab. so what i did is created one class and adding that everytime on button click. The class name is q2a2_add. This is a panel as well. The image for this is as follows...
After having some three items the app looks like
The code for this is:
public void addclass(int a) {
if(jTabbedPane1.getTabCount()<13) { //variable name of TabbedPane
String s=(String) mainCB.getItemAt(a); //mainCB is the variable name of main combobox
int dont=0;
for(int j=0;j<tabname.length;j++){ //just to ensure two accounts should not be same
if(s.equals(tabname[j])){
dont=1;
break;
}
}
if(dont==0){
for(int j=0;j<12;j++) {
if(index[j]==0){
q2a2_add subpanel2=new q2a2_add(this); //calling the second class
jTabbedPane1.add(s,subpanel2); //here adding panel
subpanel2.heading(s); // heading() method is defined in q2a2_add() which rename the jTextField to be same as argument s;
tabname[j]=s;
index[j]=1;
break;
}
}
}
else {
JOptionPane.showConfirmDialog(null, (String) mainCB.getItemAt(a)+" is already created","Information", JOptionPane.PLAIN_MESSAGE);
}
}
else {
JOptionPane.showConfirmDialog(null, "Account Overload. Delete wrong account and then create","Caution", JOptionPane.PLAIN_MESSAGE);
}
}
Now my question is. As seen in the function. everytime same class has been called and added. How can i access the various comboboxes and textboxes in different tabs. I want to store and opearate values entered by the user. Like for example- how to read inputs from Accounts Receivable, Accounts Payable and Office Supplies differently.
Please reply.
I would expose the functionality that you require within your q2a2_add class. For instance, if you want to change the textbox value, add a function inside the q2a2_add class called setTextBoxValue() that takes a String parameter. Inside that function, you can set the textbox value. The same goes for retrieving information from it. The only remaining problem is how to keep track of the different tabs. What I would recommend (which may simplify what you already have) is to create a HashMap which maps String types to q2a2_add types. Then, when you want to add a new tab panel, you can just check if the String exists in the HashMap instead of searching through to check the titles. If it doesn't exist, you can add it to a HashMap stored inside of your outer JPanel class. Then, when you want to access the tabpanels, you can simply access them by string inside the HashMap and get/set their properties as you please.