I am aware of existing error dialogs but I am trying to create my own dialog from scratch.
public class ExceptionDialog extends Dialog {
private Button okButton;
private SpanLabel errorMessage;
private Label title;
public ExceptionDialog(String titleText, String messageText, String buttonText) {
super();
this.setLayout(new BorderLayout());
okButton = new Button(buttonText);
errorMessage = new SpanLabel(messageText);
title = new Label(titleText);
this.add(BorderLayout.NORTH, title);
this.add(BorderLayout.CENTER_BEHAVIOR_CENTER, errorMessage);
this.add(BorderLayout.SOUTH, okButton);
this.setAutoDispose(false);
this.setDisposeWhenPointerOutOfBounds(true);
this.showStretched(BorderLayout.SOUTH, true);
this.setTransitionInAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_VERTICAL, true, 1000));
this.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_VERTICAL, false, 1000));
Dialog thisDialog = this;
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
System.out.println("BUTTON CLICKE");
thisDialog.dispose();
}
});
}
}
The problem: I noticed that on initialization, the dialog is showing without really calling ex.show(). Also, the button does not work, the only way to get the dialog to disappear is by clicking somewhere else on the screen.
Form hi = new Form("Hi World", BoxLayout.y());
hi.add(new Label("Hi World"));
hi.show();
ExceptionDialog ex = new ExceptionDialog("A", "B", "C");
Then I tried appending ex.show() to the code above. Now the dialog gets shown twice. The second time with a working button dismissing the dialog.
showStretched is show it will show the dialog and block until the dialog is disposed.
Related
I think I'm missing some imports, especially importing Button for the CodenameOne Hello World program from the CodenameOne.com webpage. Please tell me what I need to add to this program to put the button on the program and react to a button click. The program compiles and runs, but it does not display the button.
Here is the code:
package CodenameOneHelloWorld;
import static com.codename1.ui.CN.*;
import com.codename1.ui.*;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.io.Log;
import java.io.IOException;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.io.NetworkEvent;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class MyApplication {
private Form current;
private Resources theme;
public void init(Object context) {
// use two network threads instead of one
updateNetworkThreadCount(2);
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature
Log.bindCrashProtection(true);
addNetworkErrorListener(err -> {
// prevent the event from propagating
err.consume();
if(err.getError() != null) {
Log.e(err.getError());
}
Log.sendLogAsync();
Dialog.show("Connection Error", "There was a networking error in the connection to " + err.getConnectionRequest().getUrl(), "OK", null);
});
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Hi World", BoxLayout.y());
hi.add(new Label("Hi World"));
hi.show();
Button b = new Button("Show Dialog");
hi.add(b);
b.addActionListener(e -> Dialog.show("Dialog Title", "Hi", "OK", null));
}
public void stop() {
current = getCurrentForm();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = getCurrentForm();
}
}
public void destroy() {
}
}
If you forgot some imports, the code would not compile.
The Button is not shown because you added it after hi.show().
To make your code working, you have two ways. The first is to add hi.revalidate() at the end, like this:
Form hi = new Form("Hi World", BoxLayout.y());
hi.add(new Label("Hi World"));
hi.show();
Button b = new Button("Show Dialog");
hi.add(b);
b.addActionListener(e -> Dialog.show("Dialog Title", "Hi", "OK", null));
hi.revalidate();
The second way is to add the button before hi.show(), like this:
Form hi = new Form("Hi World", BoxLayout.y());
hi.add(new Label("Hi World"));
Button b = new Button("Show Dialog");
hi.add(b);
b.addActionListener(e -> Dialog.show("Dialog Title", "Hi", "OK", null));
hi.show();
The reason is explained in the section "7.1. Layout Reflow" of the developer guide (https://www.codenameone.com/developer-guide.html):
«Layout in tools such as HTML is implicit, when you add something into
the UI it is automatically placed correctly. Other tools such as
Codename One use explicit layout, that means you have to explicitly
request the UI to layout itself after making changes! [...] When
adding a component to a UI that is already visible, the component will
not show by default. [...] That is why, when you add components to a
form that is already showing, you should invoke revalidate() or
animate the layout appropriately. [...]»
I am fairly new to Javafx and I would like to be able to add "Actions" to my toolbar buttons for example "Tutorial" to open a PDF from the project root.
Im a bit stumped and I wonder, is there an easy to way add buttons with actions to this code?
#Override
public void start(Stage primaryStage) throws Exception {
Button btnNewGame = new Button("New Game");
Button btnConcede = new Button("Concede");
Button btnNetwork = new Button("Network");
Button btnTutorial = new Button("Tutorial");
ToolBar toolBar = new ToolBar();
toolBar.getItems().addAll( new Separator(), btnNewGame, btnConcede, btnNetwork, btnTutorial);
BorderPane pane = new BorderPane();
pane.setTop(toolBar);
pane.setCenter(createContent());
Scene scene = new Scene(pane, 640, 675);
primaryStage.setTitle("Dam spill - OBJ2000 Eksamen 2016");
primaryStage.setScene(scene);
primaryStage.show();
}
try this:
button.setOnAction(event -> {
System.out.println("button pressed");
} );
In form I embedded WebBrowser component with lots of html contents (Mainly Table, buttons ) for rich ui. Is it possible to handle event on clicking html button ?
Sure, look at the kitchen sink demo for a sample.
Generally just navigate to a URL on the event and implement your own BrowserNavigationCallback to handle navigation to that specific URL.
This is the code from the Kitchen Sink demo notice the setBrowserNavigationCallback block:
final WebBrowser wb = new WebBrowser();
if(wb.getInternal() instanceof BrowserComponent) {
Button btn = new Button("Add");
final TextArea content = new TextArea();
Container north = new Container(new BorderLayout());
north.addComponent(BorderLayout.CENTER, content);
north.addComponent(BorderLayout.EAST, btn);
cnt.addComponent(BorderLayout.NORTH, north);
content.setHint("Add to web document");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
((BrowserComponent)wb.getInternal()).execute("fnc('" + content.getText() + "');");
}
});
((BrowserComponent)wb.getInternal()).setBrowserNavigationCallback(new BrowserNavigationCallback() {
public boolean shouldNavigate(String url) {
if(url.startsWith("http://sayhello")) {
// warning!!! This is not on the EDT and this method MUST return immediately!
Display.getInstance().callSerially(new Runnable() {
public void run() {
((BrowserComponent)wb.getInternal()).execute("fnc('this was written by Java code!')");
}
});
return false;
}
return true;
}
});
}
I tried to use html page in my code for that i found way from kichensink application, i am using same code and same page.html file applicatin working on simulator but not working on devices. Ondevices i got a blank screen. Below is my code. Please help me on this.
void ShowForm()
{
Form f = new Form("testweb");
Container cnt = new Container(new BorderLayout());
cnt = createDemo();
f.setLayout(new BorderLayout());
f.addComponent(BorderLayout.CENTER, cnt);
f.show();
}
public Container createDemo() {
Container cnt = new Container(new BorderLayout());
final WebBrowser wb = new WebBrowser();
if(wb.getInternal() instanceof BrowserComponent) {
Button btn = new Button("Add");
final TextArea content = new TextArea();
Container north = new Container(new BorderLayout());
north.addComponent(BorderLayout.CENTER, content);
north.addComponent(BorderLayout.EAST, btn);
cnt.addComponent(BorderLayout.NORTH, north);
content.setHint("Add to web document");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
((BrowserComponent)wb.getInternal()).execute("fnc('" + content.getText() + "');");
}
});
((BrowserComponent)wb.getInternal()).setBrowserNavigationCallback(new BrowserNavigationCallback() {
public boolean shouldNavigate(String url) {
if(url.startsWith("http://sayhello")) {
// warning!!! This is not on the EDT and this method MUST return immediately!
Display.getInstance().callSerially(new Runnable() {
public void run() {
((BrowserComponent)wb.getInternal()).execute("fnc('this was written by Java code!');");
}
});
return false;
}
return true;
}
});
}
cnt.addComponent(BorderLayout.CENTER, wb);
wb.setURL("jar:///page.html");
return cnt;
}
Hi,I did few changes setlayout for container and add to another cotainer with scrollable true for container and scrollable false for form but now it's giving me error on devices and error is: "web page not available" page.html not found. Whereas page.html is already placed in src with .res file and application on simulator working fine.
Regards,
Jeny
You can't make a border layout scrollable, including nested scrollables and scrolling native+Codename One widgets in sync is probably not a good idea.
Which device are you having a problem on? There was an issue with browser component on Android for some use cases, its fixed now.
I am following this exactly:
http://msdn.microsoft.com/en-us/library/ms185301.aspx
but can't get it to work. The form appears when I try and add my new item, but when I input text and click the button, nothing happens.
For posterity's sake here is my code:
The non-empty methods in the Wizard class which extends IWizard
public void RunStarted(object automationObject,
Dictionary<string, string> replacementsDictionary,
WizardRunKind runKind, object[] customParams)
{
try
{
// Display a form to the user. The form collects
// input for the custom message.
inputForm = new UserInputForm();
inputForm.ShowDialog();
customMessage = inputForm.get_CustomMessage();
// Add custom parameters.
replacementsDictionary.Add("$custommessage$",
customMessage);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
// This method is only called for item templates,
// not for project templates.
public bool ShouldAddProjectItem(string filePath)
{
return true;
}
The user input form code:
public partial class UserInputForm : Form
{
private string customMessage;
public UserInputForm()
{
InitializeComponent();
}
public string get_CustomMessage()
{
return customMessage;
}
private void button1_Click(object sender, EventArgs e)
{
customMessage = textBox1.Text;
this.Dispose();
}
}
And the button is indeed named button 1:
this.button1.Location = new System.Drawing.Point(200, 180);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(100, 40);
this.button1.TabIndex = 0;
this.button1.Text = "Click Me";
this.button1.UseVisualStyleBackColor = true;
So I don't have much experience with Windows Forms (do web apps), but I am following the directions on MSDN and it's pretty clear cut. Any suggestions? Can anyone else get this to work?
Okay I figured it out. I had to add the event handler in the form's constructor manually:
public UserInputForm()
{
InitializeComponent();
button1.Click += button1_Click;
}
Why this isn't in the documentation on MSDN boggles my mind.
If you use the WinForms designer mode to drag your button from the Toolbox, and then double-clicked the button in the designer view, it would have added the event handler and stubbed that Click method for you. Just FYI.