Custom swing JTextComponent [closed] - java

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I want to create a JTextArea which looks like JTextArea, acts like JTextArea, responds like JTextArea, speaks like JTextArea, moves like JTextArea, etc, but is not JTextArea.
To make it short, I'd like to create a custom swing component based 100% on JTextArea. Once I do that, I'll be able to change different otherwise hard-coded properties of a JTextArea and make my own customised JTextArea. There are no predefined swing components that are designed the way I need them to be, but JTextArea is the closest, that why I choose it.
I'd like to change the spacing inbetweem the rows of a JTextArea. And no, I don't want to use JtextPane, I've tried, it doesn't work with my program, it calcualtes it position diferently, it look diferently, and applying the JtextArea border just messes thing up further.
I'm not trying to extend the JTextArea, I'm trying to create a custom JTextArea, as in custom swing component, with changed hard-coded properties that are not configurable trought JTextAreas methods.
However, I have no idea how to do it. I've been looking it up on the internet, but there is only an extensive guide about building your own component from stracth...
Figuring that out will take a lot of time and will not really solve my problem.
Only thing I have to do is create a class (or several classes) that will contain everyting that builds JTextArea. Start from JTextComponent level and copy all the lower level classes that are used in creating JTextArea. I'd also like to note that I use Nibus look and feel, I think that there may be some classes that would need to be included for the custom JTextArea to function properly under that LAF.
I've looked into the swing source code, and it's full of everyting. Figuring out what classes or their parts are used in creating a JTextArea would be a time consuming nightmare, given that I have no knowledge about core swing structure and mechanics.
That's why I'm asking somebody who has the knowledge to at least list the classes that I need to replicate the JTextArea, and I'll then figure out how to compose them.
Because, if I start learning now about swing core mechanics, it'll take days and weeks before I figure it all out, but for someone who knows, it would take only a couple of minutes to list all classes that I need to focus my attention onto.
I'm trying to take a shortcut here. I don't want to fully understand swing, I just want this thing to work. Default spacing is one pixel too low, and all I want to do is just make it that pixel higher. I don't want to know how the painter paints component onto screen, I just want to know where is it called from and what does it call itself...
Thanks to anyone who takes the time.

I'd like to change the spacing inbetweem the rows of a JTextArea
My first thought was that overriding javax.swing.JTextArea#getRowHeight would be sufficient. The javadoc clearly states
Defines the meaning of the height of a row. This defaults to the height of the font.
So I was hoping that by overriding this method, you would adjust the definition and you would get more spacing between the rows. Bummer, didn't work. A quick search on the usages of that method in the JDK revealed the same. It is mainly used to calculate some sizes, but certainly not used when painting text inside the component.
By looking at the source code of the javax.swing.text.PlainView#paint method, I saw that the FontMetrics are used, and those you can easily override in the JTextArea. So second approach was to extend the JTextArea (bwah, extending Swing components but it is for a proof-of-concept)
private static class JTextAreaWithExtendedRowHeight extends JTextArea{
private JTextAreaWithExtendedRowHeight( int rows, int columns ) {
super( rows, columns );
}
#Override
public FontMetrics getFontMetrics( Font font ) {
FontMetrics fontMetrics = super.getFontMetrics( font );
return new FontMetricsWrapper( font, fontMetrics );
}
}
The FontMetricsWrapper class basically delegates everything, except the getHeight method. In that method I added 10 to the result of the delegate
#Override
public int getHeight() {
//use +10 to make the difference obvious
return delegate.getHeight() + 10;
}
And this results in more row spacing (and a caret which is way too long, but that can probably be adjusted).
A little screenshot to illustrate this (not as nice as some of the other ones, but it shows that this approach might work):
Small disclaimer: this feels like an ugly hack and might result in unexpected issues. I do hope somebody comes with a better solution.

Related

Java graphic as an object/class

I'm sorry this is probably way too basic to be on here, but it's a subject I've been struggling with for about a month now and I don't know where else to go (as far as I know there is no "noob overflow", lol).
I'm trying to create a class that would:
1. put an image on a window (a JFrame, JPanel or other container)
2. be able to support keyboard and mouse listeners
3. could have multiple instances in the same container
So anyway I've tried all the usual places - Google, YouTube, the official Java site (sorry forgot the URL) and of course here on Stack Overflow - but haven't been able to find anything even remotely similar to what I'm trying to do.
Of course, I've also considered the possiblity that maybe it can't be done at all. There doesn't seem to be any kind of standard "JImage" or "JGraphic" that works like JButton or JLabel, and for whatever reason graphics requires a completely different list of (extremely involved) processes and procedures. As an example, in this post: How to "really" draw images in a Java app - it took me 60+ lines of code and 2 classes to just come close. That project didn't work in the end because for some reason it would only let me create one instance (even it you created 2-4 in the main method, it would only display the last one you told it to add).
But anyway, assuming that I'm not trying to "re-invent the wheel" here and it is actually possible (in Java), does anyone have an idea as to how (or at least know of a better site to study it)? Unfortunately most of the sites I've visited tend to assume you know all the inner workings of images (I know what a pixel is but that's about it - Buffers, Rastars etc. are still beyond me). It would be absolutely outstanding if there were a site that would explain it in layman's terms, if such a site exists. Thanks in advance.
Just use a plain old JLabel.
Regarding your requirements:
put an image on a window (a JFrame, JPanel or other container).
You can give a JLabel an ImageIcon of the image of interest and it will display it. This can then be easily placed in any other container such as a JPanel or JFrame.
be able to support keyboard and mouse listeners
Any component that extends JComponent, such as a JLabel allows for use of MouseListener, MouseMotionListener and can listen for keyboard input via Key Bindings.
could have multiple instances in the same container
You can add as many as you'd like to any container. Just be cognizant and respectful of the layout managers in use.

How to create separate screens in Swing? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am constantly finding myself building programs where there are multiple screens. For example, consider a program where the initial layout offers two buttons: create file or edit file. Upon clicking one, it takes the user to a new screen supporting whatever button they press. Then they click a back button and it takes them back to the main screen of the program. I am wondering how to best do separate menus like this. Would it be best just to create separate methods setting up each screen, then call the appropriate one when a button (like "back" button) is clicked? This is what I was thinking of doing, but seeing as there are many ways to do this, I want to get opinions on a possibly better way of changing the screen displayed.
Thanks, AJ
Based on your 2nd comment to the original question, I think it is best to look at using Panels.
Look at using multiple panels for each of the activities you want:
JPanel firstPanel = new JPanel();
JPanel secondPanel = new JPanel();
JPanel thirdPanel = new JPanel();
Ensure all panels are hidden when initialised, and then simply swap a panel for another one upon a button click event using:
firstPanel.hide();
secondPanel.show();
Depending on the layout you use, there are also other techniques. For example, rather than removing and adding (or showing and hiding multiple panels), if you use BorderLayout you can simple "replace" a BorderLayout area with another panel and then revalidate:
container.add(BorderLayout.CENTER, thirdPanel);
container.validate();
Note also that different Operating Systems (Windows, Mac etc) will have different styles they like to adhere to. For example you mentioned a typical Windows installer; people have come to expect an installer to look and work in a certain way, but on a different OS there are a completely different set of expectations and looks.
Further reading:
Tutorial on using panels
Java SE 7 (JPanel API)
Edit:
I am wondering how to best do separate menus like this. Would it be best just to create separate methods setting up each screen, then call the appropriate one when a button (like "back" button) is clicked?
This comes down to personal preference. Do you want to initalise everything on startup and have quicker swaps between panels (or as you called them: "screens"), OR do you want a quicker inital startup and essentially have "lazy loading" of each component as and when you need it.
Personally I opt for everything during initalisation (unless there is a lot of things to do or load during your applications startup). This really comes down to personal preference.
Another edit:
Speaking about layouts, perhaps a different layout style would also help you out, something like this:
CardLayout tutorial
Hope this helps out somewhat.
Take a look at the Actions framework, it's a great way of developing common level actions for re-use
If the state of the screen depends on the state of the previous screen (e.g. like in a wizard) you can follow the steps described in this article

Swing JTable custom rendering

I have this kind of progamming task without JavaFx, instead it's Java Swing. I realized my knowledge is still limited.
I have one single JTable.
But, within this JTable I need a custome Cell Renderer.
The goal is to make this kind of JTable: Example image
My current solutions are: Example Image
Create a Single JTable:
get each Column and set its CellRenderer with a custom Renderer (below).
Create a new Class implements TableCellRenderer:
return different JPanel inside getTableCellRendererComponent
method using switch case (as column counted).
After hours, and hours, I think my current solutions is quite daunting tasks. Thus, My question is:
What are the simplest method of creating this Custom JTable to achieve the main goal as mentioned above?
you have two options
1) JPanel nested another JComponents and solve that by using standard LayoutManagers note scrolling isn't natural nor nice
2) JTable with JPanel can solve that, notice about scrolling inner JScrollPane inside another JScrollPane
I've been facing this problem for a while, and I decided to do it myself. Extending the existing implementation of a table, adding some concepts for what I expect from a table, and writting some editors/listeners for that. All the same, but with a treetable.
I'm working on this project called SUMI.
It contains a java package (ar.com.tellapic.sumi.treetable) that is an extension of a JXTreeTable from SwingLabs.
The project is being developed and I didn't provide any documentation yet. You can do what you want by creating a renderer and if needed, an editor, for lastly attaching actions to each object.
If you decide to use it and you need help, email me, I'll help you without any problem.
Or, you could read the source by your own.
Regards,
EDITED (again):
To clear a little bit this answer, I've just created a wiki page in the project wiki and put the relevant code there. If someone feels that the code should be inserted here, please let me know.
Basically, I try to explain how to find a straight solution to the renderer/editor problems you may find using JTable with your specifics needs by using part of my project, in order to get something like this:
Note that the screenshot was taken after clicking on the respective tick-button.
Once you create a nested panel for one row, as suggested by #mKorbel, you can add any number of them to a GridLayout(0, 1) in a JScrollPane. If rendering many rows becomes an issue, you can adopt the same approach used by JTable, illustrated here.
Even though, JTable can be customized to whatever you desire through cell renderer and cell editors, it is never preferred because you have to do a lot of messy codings for that. Instead, for your problem, I suggest to use JScrollPane and add your component (view panel as your sample jTable ) to its viewPort.
For this implementation, represent each rows with your custom class that extends JPanel. And add the required row components (that may be any components like jlabel, jtextfields or even jpanel too) in it. For the simplicity, you can use null layout for the row panel and add the components at any location you want.
I hope this will help you workout with your problem. If you got any problem in this implementation, feel free you ask again.

how to fit text within jtextcomponent [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am trying to develop an editor without scrollbars using jtextarea, so if the text is too long to fit within jtextarea it should be splitted into smaller substrings which could be edited within the jtextarea without showing vertical scrollbar because it is easy to get rid of horizontal one by using setLineWrap and setWrapStyleWord. I have tried to use vertical scrollbar adjusmentListener to listen to its changes but it doesnt work because jtextarea append and setText methods activated at the end of business logic, so I tried to use multithreaded and SwingWorker to invoke these methods but also doesnt work. I also tried to invoke repaint, revalidate and update methods with no hope. please help me to pass this issue and thanks in advance.
As Hovercraft Full Of Eels already suggested, you have to take a look at the Document, DocumentFilter and/or DocumentListener interfaces.
By adjusting those you have full control over what text is displayed when somebody wants to append text. You could for example remove the first part of the text before/after appending new text, hence limiting the number of lines/characters in the document.
The Swing tutorial about textcomponents contains such an example in the Implementing a DocumentFilter section, where the DocumentSizeFilter class is the one you are looking for (not part of the JDK, part of the Swing tutorial code). As already suggested as a comment in that sample code, it would be an option to remove the first part of the document when appending new text which would make the contents too long, but I leave that up to you since it is tagged as homework.
I am trying to develop an editor without scrollbars using jtextarea, so if the text is too long to fit within jtextarea it should be splitted into smaller substrings which could be edited within the jtextarea without showing vertical scrollbar because it is easy to get rid of horizontal one by using setLineWrap and setWrapStyleWord.
I'm not sure I fully understand this. Perhaps you can explain further? Why not place the JTextarea inside of a JScrollPane? What is your desired behavior if the text it contains is greater than that which the JTextArea can display?
I have tried to use vertical scrollbar adjusmentListener to listen to its changes but it doesnt work because jtextarea append and setText methods activated at the end of business logic, so I tried to use multithreaded and SwingWorker to invoke these methods but also doesnt work. I also tried to invoke repaint, revalidate and update methods with no hope.
If you want to trap entered text before it is committed to the text component, consider setting a DocumentFilter to the JTextArea's associated Document (a PlainDocument).
Thank you both Hovercraft and Robin I got it, your answers trend me to the correct way, I found the accurate answer at "Core Swing: advanced programming" book by using JTextArea.modelToView() passing the JTextArea Document Length as parameter this method returns a Rectangle object whose coordination represent the final character coordination and then compare these coordination with the bottom corner of the JTextArea to see if this final char reachs to this bottom or not.

How to increase the height of Textarea in jtable dynamically

I have a standalone application in which I have a Jtable. In my table, when I type the text, the height of the Textarea should increase dynamically with the text. How can I do this?
Can someone help me with an example how to do this?
Thanking You
Chaithanya
It wasn't clear from your question - are you using a JTextArea or a TextArea? The reason it's ambiguous is people generally don't mix and match the light and heavy-weight frameworks (e.g. put awt components within a swing component).
If it's a JTextArea, I think your best bet is probably to use a DocumentListener.
DocumentListener myListener = ??;
JTextArea myArea = ??;
myArea.getDocument().addDocumentListener(myListener);
http://java.sun.com/docs/books/tutorial/uiswing/components/generaltext.html#doclisteners
I think what you'll need to do is listen for changes, and whenever something is added to the file, call the getLineCount() method, and compare it with the getRows() method. If it's broken the threshold, then use a setRows() call to increase the number of rows.
Will probably need to file some sort of UI change, especially to propagate up to the JTable.

Categories