JTextPane.setEditable() doesn't work if there is no text in the JTextPane yet. Why? (partially solved) - jtextpane

I am trying to stop a JTextPane from receiving specific letters to insert into its text, so I can insert different letters instead without having to delete the original ones first (and having them annoyingly blink into existence for a moment anyways). My solution so far would be having the press of the key associated with any such letter set the JTextPane uneditable, then have the release set it editable again. I was going to follow this up with changing the text so my chosen alternative letter would show up – but when I tried my code without said followup to see if it would work at all, I noticed that the JTextPane stays uneditable (or maybe disappears) if I press one of the keys in question first thing before typing anything else. (This also happens if I already typed some other text but then deleted it again)
Any ideas what could have gone wrong?
This is my code:
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.SpringLayout;
import javax.swing.JTextPane;
import java.awt.Font;
import javax.swing.Action;
import javax.swing.AbstractAction;
import java.awt.event.ActionEvent;
import javax.swing.KeyStroke;
class Mainclass
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
Container pane = frame.getContentPane();
SpringLayout layout = new SpringLayout();
JTextPane line = new JTextPane();
Font font = new Font("Palatino", Font.PLAIN, 36);
line.setFont(font);
Action freeze = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
line.setEditable(false);
}
};
Action unfreeze = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
line.setEditable(true);
}
};
line.getActionMap().put("freeze", freeze);
line.getActionMap().put("unfreeze", unfreeze);
line.getInputMap().put(KeyStroke.getKeyStroke("I"), "freeze");
line.getInputMap().put(KeyStroke.getKeyStroke("J"), "freeze");
line.getInputMap().put(KeyStroke.getKeyStroke("released I"), "unfreeze");
line.getInputMap().put(KeyStroke.getKeyStroke("released J"), "unfreeze");
pane.setLayout(layout);
pane.add(line);
frame.setSize(1000, 250);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
line.getPreferredSize();
frame.setVisible(true);
}
}
PS: I found out that the problem does not occur if I force the JTextPane to always take up some space (stretching it out across the JFrame's contentPane using my Springlayout), but I would still like to know what caused the problem in the first place.

Related

JDialog doesn't size correctly with wrapped JTextArea

While making a program, I noticed a bug with the JOptionPane.showMessageDialog() call. I use a button to create a JTextArea that wraps and then display a dialog containing this text area.
If the text area is too large, however, the dialog does not size itself correctly to the height of the JTextArea. The Dialog cuts off the OK button in this example.
I replicated the bug in the following code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogBug {
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final String text = "looooooooooooooooooooooong text looooooooooooooooooooooooooooooooooooooong text";
JButton button = new JButton();
button.setPreferredSize(new Dimension(30, 30));
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JTextArea area = new JTextArea(text, 0, 50);
area.setEditable(false);
area.setLineWrap(true);
area.setWrapStyleWord(true);
area.append(text);
area.append(text);
area.append(text);
JOptionPane.showMessageDialog(frame, area, "why does it do this", JOptionPane.WARNING_MESSAGE);
}
});
frame.add(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
I would post a picture, but I don't have enough reputation...
Is there a way to fix this without having to use a JScrollPane?
Here's a screenshot:
If you run the pack command on the dialog (a function in the Window class) it will resize based on subcomponents. For your case you will have to rewrite without using the showMessageDialog() to get the resize to work (so make the dialog first, add the text, pack, then show it)
Dialog b = new Dialog();
// add stuff
b.pack();
For my test code it worked perfectly to get the dialogs to be the right sizes
Without pack()
With pack()

JavaFX 2 dynamic dot loading

I wanna create some loading dots like this:
At 0 second the text on the screen is: Loading.
At 1 second the text on the screen is: Loading..
At 2 second the text on the screen is: Loading...
At 3 second the text on the screen is: Loading.
At 4 second the text on the screen is: Loading..
At 5 second the text on the screen is: Loading...
and so forth until I close the Stage.
What is the best / easiest way to make that in JavaFX? I've been looking into animations/preloaders in JavaFX but that seems to complex when trying to achieve this.
I've been trying to create a loop between these three Text:
Text dot = new Text("Loading.");
Text dotdot = new Text("Loading..");
Text dotdotdot = new Text("Loading...");
but the screen stays static...
How can I make this work correctly in JavaFX? Thanks.
This question is similar to: javafx animation looping.
Here is a solution using the JavaFX animation framework - it seems pretty straight forward to me and not too complex.
import javafx.animation.*;
import javafx.application.Application;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
/** Simple Loading Text Animation. */
public class DotLoader extends Application {
#Override public void start(final Stage stage) throws Exception {
final Label status = new Label("Loading");
final Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new EventHandler() {
#Override public void handle(Event event) {
String statusText = status.getText();
status.setText(
("Loading . . .".equals(statusText))
? "Loading ."
: statusText + " ."
);
}
}),
new KeyFrame(Duration.millis(1000))
);
timeline.setCycleCount(Timeline.INDEFINITE);
VBox layout = new VBox();
layout.getChildren().addAll(status);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
stage.setScene(new Scene(layout, 50, 35));
stage.show();
timeline.play();
}
public static void main(String[] args) throws Exception { launch(args); }
}
Have you considered to use a Progress Indicator or a Progress Bar? I think they can be a good solution to show an animation and avoid problems.
I've been able to do it in JavaFX, not with Animations, but using the concurrency classes from JavaFX.
I let you the code here in a gist. I think it isn't very intuitive, because I prefer a progress indicator. And maybe it isn't the best solution, but maybe this will help you.
Cheers

Lwuit touch screen strange behaviour

I am making an application using LWUIT.
There is a form
There is a list embedded on the form.
The list has 5 elements.
Initially, when I first load the app, if I choose the 1st element, 2nd gets chosen; when I choose the second the 3rd gets chose and and so on (Weird!)
I am not able to click any button on the screen either
next what I do is, shift to a different from using arrow keys (of the keyboard... I am running the app on a simulator btw)
Then I come back to the first form and now everything works as expected(no weird behaviour).
What could be the issue?
I am using Sun Java Micro Edition SDK 3.0 (default touch screen for testing)
My code is:
List dummy = new List();
dummy.addItem("wewerwer");
dummy.addItem("wewerdswer");
dummy.addItem("wewqweerwer");
dummy.addItem("dscxwewerwer");
dummy.addItem("jhgwewerwer");
mainListForm.setLayout(new BorderLayout());
mainListForm.addComponent(BorderLayout.CENTER,dummy);
mainListForm.show();
What could possible be going wrong here?
UPDATE 1
I think there is a bug here. I have attached the complete code below along with the screen shot
import javax.microedition.midlet.*;
import com.sun.lwuit.*;
import com.sun.lwuit.events.*;
import com.sun.lwuit.plaf.UIManager;
import com.sun.lwuit.util.Resources;
public class Demo extends MIDlet implements ActionListener {
private Form mForm;
List abc;
public void startApp() {
Display.init(this);
try {
Resources r = Resources.open("/Test.res");
UIManager.getInstance().setThemeProps(r.getTheme(
r.getThemeResourceNames()[0])
);
} catch (Exception e){
System.out.println(e.toString());
}
if (mForm == null) {
Button click = new Button("Press me!");
click.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.out.println("I have been pressed");
}
});
abc = new List();
abc.addItem("Str1");
abc.addItem("Str2");
abc.addItem("Str3");
abc.addItem("Str4");
abc.addItem("Str5");
abc.addItem("Str6");
Form f = new Form("Hello, LWUIT!");
abc.addActionListener(this);
f.addComponent(abc);
Command exitCommand = new Command("Exit");
f.addCommand(exitCommand);
f.addCommandListener(this);
f.addComponent(click);
f.show();
}
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void actionPerformed(ActionEvent ae) {
System.out.println(abc.getSelectedIndex());
}
}
So now when I click on 'Str1' of the list Str2 gets selected and so on.
IDE: Netbeans
Emulator: Default Touch screen phone
On the action event set the list to active again after the event by invoking setHandlesInput(true)
OK....so this is how you resolve it.
After the form is displayed remove the list from the form and again add it to the form and then repaint the form.
Earlier Code
1) form.addComponenet(BorderLayout.center,list);
2) form.show();
Word Around for the problem
1)form.addComponenet(BorderLayout.center,list);
2)form.show();
3)form.setScrollable(false);
I know its kind of strange, but this way the list index selection works smooth for touch screen phones.

issue with lwuit right-to-left label ticker

I was trying to set ticker on a Label with lwuit 1.5, faced this issue:
if I set label.setRTL(true) and then call
label.startTicker(UIManager.getInstance().getLookAndFeel().getTickerSpeed(), true);
ticker just shows first 21 characters of the label's text and ignores the rest.
I've tried:
label.setRTL(false);
label.startTicker(UIManager.getInstance().getLookAndFeel().getTickerSpeed(), true);
it shows up OK, the text goes from left to right, but when I set this in a FocusListener (cause ticker should start when the label receive focus and stop after it loosed focus) it just change direction (goes from right to left).
here's what i do:
Label test = new Label();
Container c1 = new Container(new FlowLayout());
test.setText("1234567890ABCDEFGHIJ1234567890");
test.setFocusable(true);
test.setRTL(false);
test.addFocusListener(new FocusListener (){
public void focusGained(Component cmpnt) {
((Label)cmpnt).setRTL(false);
((Label)cmpnt).startTicker(UIManager.getInstance().getLookAndFeel().getTickerSpeed(), false);
}
public void focusLost(Component cmpnt) {
((Label)cmpnt).stopTicker();
}
});
c1.addComponent(test);
Look at setLabelFor, it will ticker the label for test when test gains focus. You should probably set RTL globally in the look and feel class.
I found the problem. wrong direction happens because I've implemented focusListener before adding the label to container (c1). so I just did this:
c1.addComponent(test);
test.addFocusListener(new FocusListener (){
public void focusGained(Component cmpnt) {
((Label)cmpnt).setRTL(false);
((Label)cmpnt).startTicker(UIManager.getInstance().getLookAndFeel().getTickerSpeed(), false);
}
public void focusLost(Component cmpnt) {
((Label)cmpnt).stopTicker();
}
});
and it simply worked.
in fact I got the idea from Label class source code (lines 149 ~ 153):
// solves the case of a user starting a ticker before adding the component
// into the container
if(isTickerEnabled() && isTickerRunning() && !isCellRenderer()) {
getComponentForm().registerAnimatedInternal(this);
}
this part does not work, but I don't know why. just hope someone fix this bug.

GWT Graphics - resetting the text

I am working on a project for which i am using GWT-Graphics. I have drawing Area containing ellipse and text. When i double click on them a pop-up menu appears and gives an option to enter text. Now when i save this text i want it to appear on this drawing area in the place of the previous text.
I am trying to do this but with no luck. It keeps the old text and on top of that it includes the current text. Is there a way to have only the new text to appear.
Any input will be of great help.
Thank you.
For me this sounds like that you are adding a new Text element instead of using the existing one. I wrote a quick test and it seems to work like you want:
public class GwtTest2 implements EntryPoint {
private Text text;
public void onModuleLoad() {
DrawingArea da = new DrawingArea(400, 400);
RootPanel.get().add(da);
da.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
String newTextValue = Window.prompt("", "");
text.setText(newTextValue);
}
});
Ellipse ellipse = new Ellipse(200, 200, 100, 50);
da.add(ellipse);
text = new Text(150, 200, "Hello world!");
da.add(text);
}
}

Resources