I have made a TextFlow, as I need to use multiple font-postures (I have set particular "Text" to either italic or normal). Once I display the TextFlow, it's not selectable/copyable. All I need is the TextFlow to be selectable once it's displayed in a scene, so it can be copy/paste-able.
Text example with font-posture (only one for examples sake):
Text volumeText = new Text(volume.getText());
volumeText.setFill(Color.WHITE);
volumeText.setFont(Font.font("arial", FontPosture.ITALIC, 13));
TextFlow reference = new TextFlow(
lastNameText, miscelanous1, firstNameText, miscelanous2);
reference.setLayoutX(115);
reference.setLayoutY(480);
reference.setMaxWidth(500);
control.getChildren().add(reference);
Text and TextFlow in JavaFX are not "selectable".
There is an issue open for this : Text should have API for selecting group of characters based on their position similar to the DOM's Range.
Until the issue is taken care of, your best option is to use a 3rd party control like RichTextFX.
I think I got a nasty way of doing the similar job
Text could sense the mouse enter & exit move event
We could set a signal for mouse pressed and release event. Would be nice to have this event triggered on Textflow node
extends Text class to have mouse enter event handler, when the global signal is on and mouse enters text then copy the text to some places
and also record the text place in the textflow
using sth. like
var index = textflow.getChildren().indexof(text)
record the pair of index and text
when mouse release or exit event are triggered, sort the texts selected and generate the corresponding texts into clipboard
Related
I am currently creating a small chat program (mainly for the purpose of getting some experience with RMI and JavaFX). The chat itself is already finished, now I'm working on the GUI.
I want every chat message to be printed in some kind of text area similar to this:
Alice <19:21:35>: Hello World!
These are my problems/questions:
What JavaFX class to use for this? I found a class called TextFlow that seems to be able to do what I want, but I didn't understand how exactly it works by now. Or is a simple TextArea enough?
How can I use different formattings within one line? Using HTML?
How should I keep the received text messages within the client? Just always append them to the text area (and have them saved implicitly by the GUI)? Or should I use some kind of ObservableList that buffers the messages and the text area synchronizes with it?
The messages are received as Message objects. These objects basically just store username, message, and timestamp; each of them in a seperate attribute.
The simplest way of doing it would be through a TextArea, although there wouldn't be any neat text formatting, it would just look like a bland NotePad like program. I would recommend using a VBox and Texts. One VBox could be used to store all the Texts, and you could put the VBox in a ScrollPane for scrolling. Then, for every message, put an HBox consisting of 3 Texts. Here is an example
//Put this method in your Application class
public static void addMessage(Message message){
Text username = new Text(message.getUsername());
username.setFont(Font.font("Verdana", FontWeight.BOLD, 14));
Text date = new Text(message.getTimestamp());
date.setFont(Font.font("Verdana", FontWeight.ITALIC, 12));
date.setFill(Color.GRAY);
Text message = new Text(message.getMessage());
date.setFont(Font.font("Courier New", 12));
mainBox.getChildren().Add(new HBox(username, date, message)); //mainBox being a VBox that stores all your HBoxes.
}
Obviously, change this to suit your needs, and please change the styling. I just gave an example. This is what I have done before, and with the right styling, it looks a lot nicer than just slopping on a TextArea.
If your formatting requirements are fixed, then Text and TextFlow would be a good place to start. Each text node can be assigned a style either in code or via CSS. Put multiple text nodes together into a TextFlow. Put the TextFlow node into a layout container. Start with a VBox for testing, but I would suggest using a TableView once you get the basics working. The javadoc for TextFlow has snippets of sample code that should get you going.
For a pure JavaFX solution then use multiple Text nodes, styled with CSS. Either set formatting properties on each node, or assign a style and use an external .css file. Or if you want to consider third-party components, then something like this: https://github.com/TomasMikula/RichTextFX might be a good place to start.
You definitely want to separate your data model from your display model (or view, if you want to use that terminology). Build a data class (e.g, Message). If you hold your message data in an ObservableList of Message objects then you can bind it to a TableView, and have the table automatically update as you add or remove entries in the list. Add code to the table cell factories to control how you render each cell from your data model (e.g., by creating a TextFlow to draw the content).
I am making a text application where I can change the text to bold (I will add more in the future).
I put the bold option in a JMenu as a JCheckBox.
I want this checkbox to get selected or deselected depending on whether the insertion point (the blinking line) is on a bold or normal text. Just like it is in Microsoft Word.
The application
Quick answer from my phone:
You need to add a CaretListener to the document. When triggered, you will detect the character style with StyledDocument.getCharacterAttributes. To get the bold attribute, you check it with StyleConstants.isBold. Be careful to not trigger your bold action while setting the check box state.
I was wondering if it was possible to drag the text from a JLabel, out of the java application onto a pdf form for example.
If it is possible, could you point me in the right direction please?
Its easy.What i woud do- Put listener onto JLabel, take text on event that you pick.Copy text from the JLabel value into Clipboard,
Now you have text that you can manipulate.
Drag effect.=Use (with combination of the previous listener) JNativeHook lib to get GLOBAL EVENTS of java application and outside.
Listen for dragging(Do on your own its easy) , on mouse release onto your pdf input text.
You might have to simulate mouse click(right after release) to select field (via robot class) to actualy SELECT THAT FIELD,so you can input text.
Input text part=Use robot class to insert string char by char.
This will work well.I dont have any other idea atm that woud be this easy to implement.
You can also (fool user) with effect of floating text etc if you put transparent window over the top and check mouse location on screen.
This is a problem that has vexed me for a number of years. The user is scrolling through a text document contained in an JEditorPane which is in turn contained in a JScrollPane. The user performs some function using a button which changes the text (it highlights certain sections of the text). I then refresh the document in the JeditorPane to reflect the highlighting (using html tags). But when I do this, the document scrolls back to the top. I want the document to stay in the same position that the user was in right before taking the action. Note, the user has not selected any text in the document so I can't scroll to a selection point (that technique does work if text is selected, but alas I can't do it in this case). How do I preserve the position in the JScrollPane and scroll to the position that the user was at prior to taking the action?
Thank you
You can use JViewport.scrollRectToVisible() to jump to a certain section of a document in a JScrollPane. You can snapshot the current position before performing the action with JViewPort.getViewRect()
http://download.oracle.com/javase/6/docs/api/javax/swing/JViewport.html
Note, the user has not selected any text in the document so I can't scroll to a selection point
Get the selection indices before updating, then call setCaretPosition(previousStart) then moveCaretPosition(previousEnd) afterwards.
You can also use:
Point p = scrollPane.getViewport().getViewPosition();
// do stuff
scrollPane.getViewport().setViewPosition();
I tried all of these potential solutions. Unfortunately, for whatever reason, they didn't work. This is the code that actually solved the problem for me.
/* This code is executed, before the JeditorPane is updated: */
int spoint = detailpane.scrollPane.getVerticalScrollBar().getValue();
/* Then to restore the scroll to where it was before the update, the following code is executed*/
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
detailpane.scrollPane.getVerticalScrollBar().setValue(spoint);
}
});
/* Note because of the usual weirdnesses associated with Swing which is not thread safe, you need to enclosed the setValue within in a Runnable. */
I'm writing my 1st Java program (in Netbeans) and I'm lost. I have 2 questions at the moment, if anyone is kind enough to help me.
Here's what the program is supposed to do:
take 1 of 4 "status" options, plus a 5 digit number (both of these items are entered by a user via a touch-screen monitor) and then email this info to someone with the subject line of: "Item #[5 digit number from JFormattedTextField] is currently [1 of 4 possible status options].
Email command would command after user clicks "enter" button, and then user clicks "OK" on a pop-up which asks user to confirm message about to be emailed. As far as my 3rd question, it's about the e-mailing part, and I figured that would be a another thread after I get this button & text field stuff ironed out.
Here's a picture of the touch screen UI I have so far:
(can't post images as a rookie, go to krisbunda.com/gui.png for this image)
Question #1:
the 4 status options (4 JButtons) are wrapped inside of a JPanel. I want the most recent button to have been pushed in the "statusPanel" JPanel to change the background to blue and the button text to white.
Can I put a mouselistener on the button's parent JPanel to listen for click events on the children (the 4 status JButtons), and then whichever button was last clicked, it will turn blue w/ white text? Please point me in the right direction.
Question #2:
I have a JFormattedTextField named "display" that shows the numbers as they're clicked, which are appended from a StringBuffer named "current". I want the text field to only accept a total of 5 numbers.
When I tried putting a mask of "#####" on the field, it would only chime a warning beep when I pushed the number pad's buttons. Currently I've chosen "Category: number" and "Format: custom" and then typed "#####" in the "Format:" field. This allows me to click number buttons and see their text displayed, but it doesn't stop me from typing more than 5 characters.
I'm doing this through the "Properties> FormatterFactory" dialog box. A screen shot is shown below:
(go to krisbunda.com/text-formatterFactory.png to view this image)
And here's the code I have so far:
(my post was too long with this code, so go to: krisbunda.com/java-sampleCode.txt to view)
Thanks in advance for any help!
Your code looks fine, and you already have fields set up to hold references to all your buttons, so now you just need to write the code inside the status setting buttons and then make them call a subroutine with the new status. This subroutine should then reset all the buttons to their default color and then set the special selected color on the button that corresponds to the new or existing status.
Edit: adding code here in response to your comment...
Firstly, never use == with Strings. You MUST use equals() otherwise when you get two Strings that are identical, but are different objects, they will not be the same and your comparisons will fail.
There are much better ways of coding this up, including using enums etc. but this should work for you:
// Reset all the buttons
outsideNotReadyButton.setBackground(...);
loadedButton.setBackground(...);
outsideReadyButton.setBackground(...);
shippedButton.setBackground(...);
// Now set the one of the button's colors conditionally
String status = ...
if(status.equals("SHIPPED")) {shippedButton.setBackground(Color.BLUE);}
else if(status.equals("LOADED")) {loadedButton.setBackground(Color.BLUE);}
// ...and so on
An ActionListener is the more common approach to buttons, as discussed in How to Use Buttons, etc. A FocusListener, also used in this example, is one way to change a button's appearance in the way you describe.
An sscce showing just your JFormattedTextField problem will be more helpful. Several such examples may be found in the article How to Use Formatted Text Fields.