Non resizable window with JFace - java

I how it's possible to setup non resizable window with JFace API. Consider code below that creates application window. I can't find any methods to setup window as not resizable on shell object or application window parent. Is there something I'm missing?
public class Application extends ApplicationWindow
{
public Application()
{
super(null);
}
protected Control createContents(Composite parent)
{
prepareShell();
return parent;
}
protected void prepareShell() {
Shell shell = getShell();
shell.setSize(450, 300);
}
public static void main(String[] args)
{
Application app = new Application();
app.setBlockOnOpen(true);
app.open();
Display.getCurrent().dispose();
}
}
Thanks for your help.

As far as I understand you, you want to set shell style bits prior to the shell creation.
Simply add
#Override
public void create() {
setShellStyle(SWT.DIALOG_TRIM);
super.create();
}
to your class, to do so. This omits the SWT.RESIZE style bit, therefore prevents resizing..

Related

What are my options for parent when using JFileChooser?

I'm trying to show a window for file choosing as it follows:
public class XMLElementCounter() {
public static void main(String[] args) {
elementCounter();
}
static void elementCounter() {
try {
final FileChooser fc = new JFileChooser(defaultDirectory);
int returnVal = fc.showOpenDialog(parent);
...
}
}
First i declared the elementCounter directly in the main function and i called as parent fc, which showed the window as expected, but as i modularized it, it stopped showing anything. When i use null, it shows the screen behind every other window, which is annoying.
How can i know which is the parent i'm looking for, and where can i learn about it?

change javafx object attributes

I`m trying to develop a javafx project in such a manner that the business logic and the view are seperated. Frankly, I don´t know if i realised it right.
My idea was to create a class view. Simplified it looks like this:
public class View extends Application {
private Pane screen = new Pane();
private Rectangle rect;
private Scene scene = new Scene(screen, 500, 500);
public View(){
rect = new Rectangle(10, 10, 100, 100);
rect.setFill(Color.WHITE);
rect.setStroke(Color.BLACK);
screen.getChildren().add(rect);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Rectangles");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public void setColor() {
rect.setFill(Color.BROWN);
}
}
Objects of that class can be created and used in this way in the main method of another class including the bussiness logic:
View foo = new View();
foo.main(null);
Unfortunately, I can´t change its attributes afterwards. Therefore, this statement doesn´t have any effect.
foo.setColor();
Like I said, maybe this is a wrong approach. I´m not very familiar with javafx, so please indulge me.
You need to remove the main method from your View. In your logic-class you have to save the root Pane you set. And then you can put/change your View into your Pane. Your view cannot extend Application anymore then! Make it extend some Pane.
private final BorderPane rootPane = new BorderPane(); // Class field
// in your start method
final Scene scene = new Scene(rootPane);
primaryStage.setScene(scene);
//Change View like this:
View v = new BView();
rootPane.setCenter(v.getRec());
// later you can set your color
v.setColor()
// Your View class:
public class View{
private Rectangle rect;
public View(){
rect = new Rectangle(10, 10, 100, 100);
rect.setFill(Color.WHITE);
rect.setStroke(Color.BLACK);
}
public Rectangle getRec(){
return this.rect;
}
}
Also have a look at this Documentatino here
Your problem is that you are creating your own instance of View. When you call the static method main(String[] args), it creates its own instance of View and shows that. Have a look at JavaFX 2.2 Application.
Therefore the instance you called foo isn't the one being shown and so changing properties has no effect. If you read the Javadoc carefully then you could probably do a hack to get the effect that you want but I wouldn't recommend it since you are relying on things that might change in the next release.
If you really want to be able to call Application methods from elsewhere you could do something like this.
In the other class:
private static View view;
public static void setView(View view) {
this.view = view;
}
Then inside the start method of View, add the line:
OtherClass.setView(this);
On another note, if you are looking for Model/View separation, it might not be a good idea to instantiate the view (application) from within the model (class containing business logic). Doing so is something of a paradox, since the Model is now dependent on the view (i.e. the Model shouldn't know about the rectangle). A better idea would be to instantiate the Model class in the start() method of and have your application work with the interface of your Model. This way your Application class acts as an adapter linking GUI controls to trigger things in your Model.

Splitting a View into several files in Swing MVC

My project follows the MVC pattern. To make it quick, I will only post the code relevant to my problem (which doesn't involve the Model). Explanations below.
Controller.java :
public class Controller {
public View myView;
public Controller() {
myView = new myJFrame(this);
}
public void displayViews() {
myView.display();
}
public void closeViews() {
myView.close();
}
}
View.java :
public abstract class View {
private Controller controller;
public View(Controller controller) {
super();
this.controller = controller;
}
public final Controller getController() {
return controller;
}
public abstract void display();
public abstract void close();
}
myJFrame.java :
public class myJFrame extends View {
private JFrame frame;
private JMenuBar myMenuBar;
public myJFrame(Controller controller) {
super(controller);
buildFrame();
}
private void buildFrame() {
frame = new JFrame();
menuBar = new JMenuBar();
...
}
#Override
public void close() {
frame.dispose();
}
#Override
public void display() {
frame.setVisible(true);
}
}
This code works perfectly. However, the buildFrame() method will soon become huge if I keep adding components, so I would like to split it and create a new class in a new file for every Swing component.
The problem is that I want my components to retain their access to the Controller. myFrame extends View, therefore the getController() method can be called anytime. But it is no longer the case when I create a separate file. Extending View doesn't seem to be an option (besides, myMenuBar already extends JMenuBar, for example).
What would you suggest?
The problem is that I want my components to retain their access to the Controller.
Fine. Create a class for the JPanels that make up your GUI, and pass an instance of View to each of them through their respective constructors.
You shouldn't extend Swing components unless you're overriding a component method. You should use Swing components.
Composition over inheritance
You shouldn't be extending View either. Passing an instance of the view is sufficient.
Read this excellent article, Sudoku Solver Swing GUI, for a better idea of how to use the MVC pattern when constructing a Swing GUI.

Adding to GWT RootPanel or just setting the default view?

I have the following GWT classes:
public class MyDefaultView extends Composite {
// Uses UiBinder and just contains all the widgets for this view.
}
public class MyDefaultActivity extends AbstractActivity {
#Inject
private MyDefaultView myDefView;
#Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
panel.setWidget(myDefView);
}
}
public class MyActivityMapper implements ActivityMapper {
#Override
public Activity getActivity(Place place) {
if(place instanceof MyDefaultPlace)
return new MyDefaultActivity();
else
return null;
}
}
public class MyAppModule implements EntryPoint {
#Override
public void onModuleLoad() {
// Lots of initialization and wiring...
// Why do I need this?!?
MyDefaultView myDefaultView = GWT.create(MyDefaultView.class);
RootPanel.add(myDefaultView);
Place myDefaultPlace = GWT.create(MyDefaultPlace.class);
PlaceHistoryHandler historyHandler = getHistoryHandler();
historyHandler.register(myPlaceController, myEventBus, myDefaultPlace);
historyHandler.handleCurrentHistory();
}
}
Why do I need to add MyDefaultView to RootPanel, if I'm just going to call PlaceHistoryHandler#handleCurrentHistory() and display MyDefaultView when the module loads?
If I shouldn't be adding MyDefaultView directly to RootPanel, then what should I be adding?
Thanks in advance!
1) You don't need to add MyDefaultView, but you need to a panel that implements AcceptsOneWidget and set that panel on the activity manager. This will take care of having your views made visible.
2) In most applications you have a part of the application that is always visible. For example a bar at the top showing among other things the user name. This kind panel needs to be added to the root panel. In that panel on the position where your views should be visible a widget/panel that implements AcceptsOneWidget should be used. This widget should be set as display in your activityManager, via setDisplay. That widget will be passed to the start method in your activity. Here is how the code to use with the ActivityManager and RootPanel could look like:
final ActivityManager activityManager = new ActivityManager(myActivityMapper, eventBus);
activityManager.setDisplay(rootView.getViewPanel());
Rootpanel.add(rootView);

GWT RootLayoutPanel - Problem rendering page from second to first (first works fine)

Sorry if this was already answered before. I did a little searching and found nothing that could solve my problem. I created an application with Spring Roo, then converted to a GWT app.
All the code generated by Spring Roo is only for CRUD. Now i want to add a Calendar for make appointments, so i need to move to another page.
I´ve added this code to
ScaffoldDesktopShell.java()
public ScaffoldDesktopShell() {
initWidget(BINDER.createAndBindUi(this));
startButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
RootLayoutPanel.get().add(new NovoPainel());
}
});
}
...
Then created a new UIbinder, called it NovoPainel() and added this code:
public NovoPainel() {
initWidget(uiBinder.createAndBindUi(this));
botao.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
RootLayoutPanel.get().clear();
RootLayoutPanel.get().add (new ScaffoldDesktopShell());
}
});
}
Everything goes fine moving from my root panel to NovoPainel, but when i need to go back to rootPanel the page doesn´t render correctly.
EX: Doesn´t show ** ValuePicker ** to click on left panel and render on center.
This is my RootPanel
and this image is when navigate from rootPanel to NovoPainel
and finally this one is returning from NovoPainel to RootPanel
You have to integrate with Roo generated architecture so that you can still benefit from Roo scaffolding.
Roo generated code hides most of behavior in _Roo_Gwt classes and it is because GWT doesn’t currently support ITDs. So changes have to be made in derived classes by overriding methods from _Roo_Gwt class.
To navigate application use Places, ActivityMapper and ActivitiManager (you can find good read on #Thomas Broyer posterous and GWT help).
If you take a look in ScaffoldDesktopShell.ui.xml - page is devided in three main areas.
ApplicationMasterActivities class is responsible for master area.
masterActivityManager.setDisplay(shell.getMasterPanel());
proxyListPlacePicker in ScaffoldDesktopApp.init() generates place change event with apropriate ProxyListPlace.
public void onValueChange(ValueChangeEvent<ProxyListPlace> event) {
placeController.goTo(event.getValue());
}
ApplicationMasterActivities class creates appropriate Activity in Master area by checking EntityProxy type contained in ProxyListPlace object.
public Activity getActivity(Place place) {
if (!(place instanceof ProxyListPlace)) {
return null;
}
ProxyListPlace listPlace = (ProxyListPlace) place;
return new ApplicationEntityTypesProcessor<Activity>() {
#Override
public void handlePet(PetProxy isNull) {
setResult(new PetListActivity(requests, ScaffoldApp.isMobile() ? PetMobileListView.instance() : PetListView.instance(), placeController));
}
#Override
public void handleOwner(OwnerProxy isNull) {
setResult(new OwnerListActivity(requests, ScaffoldApp.isMobile() ? OwnerMobileListView.instance() : OwnerListView.instance(), placeController));
}
}.process(listPlace.getProxyClass());
}
Navigation is created by listing all EntityProxy's in ScaffoldApp class
protected HashSet<ProxyListPlace> getTopPlaces() {
Set<Class<? extends EntityProxy>> types = ApplicationEntityTypesProcessor.getAll();
HashSet<ProxyListPlace> rtn = new HashSet<ProxyListPlace>(types.size());
for (Class<? extends EntityProxy> type : types) {
rtn.add(new ProxyListPlace(type));
}
return rtn;
}
To output meaningfull name in navigation menu they are rendered using ApplicationListPlaceRenderer
public String render(ProxyListPlace object) {
return new ApplicationEntityTypesProcessor<String>() {
#Override
public void handlePet(PetProxy isNull) {
setResult("Pets");
}
#Override
public void handleOwner(OwnerProxy isNull) {
setResult("Owners");
}
}.process(object.getProxyClass());
}
So you have to create new Activity.
public class SomeActivity extends Composite implements Activity{
private static SomeActivityUiBinder uiBinder = GWT
.create(SomeActivityUiBinder.class);
interface SomeActivityUiBinder extends UiBinder<Widget, SomeActivity> {
}
private AcceptsOneWidget display;
public SomeActivity() {
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public String mayStop() {
return null;
}
#Override
public void onCancel() {
onStop();
}
#Override
public void onStop() {
this.display.setWidget(null);
}
#Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
this.display = panel;
this.display.setWidget(this);
}
}
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTMLPanel>
Hello world!
</g:HTMLPanel>
</ui:UiBinder>
Create appropriate EntityProxy. It is only to obey ProxyListPlace mechanism.
public interface SomeEntityProxy extends EntityProxy {
}
Create SomeActivity in A
#Override
public Activity getActivity(Place place) {
if (!(place instanceof ProxyListPlace)) {
return null;
}
Activity activity = super.getActivity(place);
if (activity == null) {
ProxyListPlace listPlace = (ProxyListPlace) place;
if (SomeEntityProxy.class.equals(listPlace.getProxyClass())) {
activity = new SomeActivity();
}
}
return activity;
}
Add place to navigation in ScaffoldApp or override getTopPlaces in derived class.
rtn.add(new ProxyListPlace(SomeEntityProxy.class));
Set correct menu rendering text in ApplicationListPlaceRenderer
#Override
public String render(ProxyListPlace object) {
String label = super.render(object);
if(label == null) {
if (SomeEntityProxy.class.equals(object.getProxyClass())) {
label = "Some activity";
}
}
return label;
}
Code in GitHub.
GWT 2.1 introduced new classes that implements the Model-View-Places pattern (MVP). This pattern (and the GWT 2.1 concepts) are heavily based on best practices from developers who have build scalable GWT-based applications, so many people are migrating in this direction.
Roo generates a GWT 2.1 application; all of its navigational code is built on top of Activities and Places. The reason I bring this up is it sounds like you are attempting to side-step a lot of this navigational framework to implement your own. I'm not sure, but I believe your problem is coming from the fact that the MVP code is getting confused as a result.
My recommendation would be to work through the GWT MVP article linked above first. Do it completely separate of Roo, because the application that Roo generates is more complex. Once you have a good handle on it, go back through the Roo-generated application and it will likely make more sense.
You can create two div tags in your Porject.html file respectively with id firstdivtag_id1 and seconddivtag_id2.
Display first page by using
RootPanel.get("firstdivtag_id1").add(Panel1);
And then to switch over to another panel use
RootPanel.get("seconddivtag_id2").add(Panel2);

Categories