Scrollbars inside a JTable cell - java

I am trying to display HTML text inside a JTable's cell but the scrollbars arent showing up at all. Below is my code...
public class TableCellTextRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
final JTextPane jtextPane = new JTextPane();
JScrollPane scrollPane = new JScrollPane(jtextPane);
scrollPane.setPreferredSize(new Dimension(350,350));
scrollPane.setVisible(true);
jtextPane.setEditable(false);
jtextPane.setAutoscrolls(true);
jtextPane.setContentType("text/html");
jtextPane.setText(myHtmlText);
jtextPane.setVisible(true);
jtextPane.setPreferredSize(new Dimension(350,350));
//this setViewPort has no effect
scrollPane.setViewportView(jtextPane);
jtextPane.setVisible(true);
scrollPane.setAutoscrolls(true);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
JPanel jpanel = new JPanel();
jpanel.setVisible(true);
jpanel.setPreferredSize(new Dimension(360, 360));
jpanel.add(scrollPane);
return jpanel;
}
}
The scroll bars appear, but the scrolling handles dont appear. Can you please tell me what I am missing?
The table looks like this:

I'm afraid this is not going to work the way you'd want it to. The way JTables work is by obtaining a renderer component to draw the cell once, then cache it. In simplest terms, the component you're returning is basically just used to draw the cell, but it does not work the way normal components do - for instance, it does not receive events. You can use a cell editor (which will receive events), but the user would have to select the cell manually.
There are a couple of tricks you can use by installing custom mouse listeners, but this stuff will get very complicated. It'd probably be better to ask yourself if you're really looking for a JTable (as opposed to a custom layout), or if it would perhaps be possible to embed a JavaFX table.

Related

Why can't I edit the appearance of this editable jComboBox?

I have this code and MyComboBoxRenderer() seems to not work with it. It has an error in the line with comment written below.
This code is made for autosuggest. So it shows suggestion in a combobox while user types on the textfield.
public test2() {
initComponents();
jComboBox1.setRenderer(new MyComboBoxRenderer1());
jComboBox1.setBackground(new Color(0,0,0,0));
final JTextField textfield = (JTextField) jComboBox1.getEditor().getEditorComponent(); //it has error in this line
textfield.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
comboFilter(textfield.getText());
}
});
}
});
}
Maybe it has something to do with the textfield. My problem is that I wanted to edit the appearance or design of combobox. I want it to inherit the background of the frame. Like transparent. Example are in the pictures.
Here are the pictures. Please click the links below to see it.
It should be something like this
Rather than this one. This is the output of the codes above.
And here is the code I have in my combobox renderer.
public MyComboBoxRenderer1(){
setOpaque(true);
setFont(new Font ("Segoe UI Semibold", Font.PLAIN ,14));
setForeground(Color.WHITE);
}
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
setText(value.toString());
if (isSelected)
{
setBackground(Color.WHITE);
setForeground(Color.BLACK);
}
else {
setBackground(Color.GRAY);
setForeground(Color.WHITE);
}
return this;
}
}
Why is it that the renderer doesn't work with this? And what should I do to make it work? Can anyone help me please? Thank you in advance. :)
EDITED...
I've already set the background transparent. I just need to declare the background of the texfield. XD Yey.
textfield.setBackground(new Color(0,0,0,0));
textfield.setForeground(new Color(255,255,255));
But it left small portion that is still not transparent.
I tried doing an additional comboBox on my frame. But it is without the textfield. And it works just fine!
The upper is the comboBox with textfield, the one I have problem with. The lower is the one w/o textfield, I just tried if the code will work with a normal comboBox. I need to make it look like the lower one.
jComboBox1.setRenderer(new MyComboBoxRenderer1());
jComboBox1.setBackground(new Color(0,0,0,0));
jComboBox2.setRenderer(new MyComboBoxRenderer1());
jComboBox2.setBackground(new Color(0,0,0,0));
It has the same code. But it doesn't work with the other one. Maybe it's because of the textfield again?? :(((
jComboBox1.setBackground(new Color(0,0,0,0));
Don't try to use transparent colors. Swing does not know how to paint transparent colors properly. See: Background With Transparency for more information.
Instead you change the opaqueness of the component:
component.setOpaque( false );
In the case of the combo box you need to worry about the component and the renderer, so you might use:
comboBox.setOpaque(false);
((JLabel)comboBox.getRenderer()).setOpaque(false);
However, this will now cause a problem with the dropdown list. Since the rendering is now transparent you won't see the row selections.
Haven't tested this but a possible solution if to alter the opaqueness of the renderer based on the item being rendered.
The code might be:
public Component getListCellRendererComponent(
JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
setOpaque(index == -1 ? false : true);
// add custom painting here
return this;
}
The -1 indicates the item in the combo box is being rendered as oppose to an item in the list.

JTable inside JScrollPane cell size and table size

I have this code for show some data inside a JTable:
public class ShowResults extends JFrame {
public ShowResults(List<String> list) {
setSize(1000, 1000);
setLocationRelativeTo(null); //center
setVisible(true);
String[][] table_data = new String[pics.size()][table_header.length];
for (int i = 0; i < pics.size(); i++) {
//Fill table with data
}
JTable table = new JTable(new DefaultTableModel(table_data, table_header)) {
#Override
public boolean isCellEditable(int row, int column) {
//disable table editing
return false;
}
};
JScrollPane scroll_pane = new JScrollPane(table);
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
table.getTableHeader().setReorderingAllowed(false);
table.getTableHeader().setResizingAllowed(false);
this.setLayout(new FlowLayout());
this.add(scroll_pane);
}
}
But table doesn't look as i expect. I would that scroll bar in only vertical (now is horizontal) and header of table show entire header names (now table is wrapped for some reason i don't know).
How can i do?
I would that scroll bar in only vertical (now is horizontal) and header of table show entire header names (now table is wrapped for some reason i don't know).
The reason is you set a new FlowLayout as the content pane's layout manager. This layout manager honors the components preferred size and therefore prevents the scroll pane resizes as you wish. I'd leave the default layout manager, which is BorderLayout, and add the scroll pane to the CENTER location.
On the other hand, you should make your frame visible after adding all your components to its content pane.
I would use a grid layout. Also try removing the scroll_pane for now and see if that makes a difference. I ran into problems using JScrollPane myself.

Double clicking on a table JButtton does not work and is just displaying class name of JButton

I have a JTable that just contains one item which is a JButtton that has an icon which is set to the JFreeChart generated chart.
If you click the button it launches a new window with the JFreeChart chart.
I have a cell renderer for the button which simply returns the JButton object that contains the chart item.
If I single click on the button it will launch the new window.
But if I double click on the button the new window launches, but the icon on the button, which used to be the JFreeChart, changes to just a text string with the class name path of the JButton with the class field values.
They other way I can get this behavior to happen is if I remove the cell renderer then the JButton just diplays the class name. So I'm not sure what is going on and have played around with it a ton and haven't made any progress. I was going to post some code but there is just too much of it.
If anybody has any ideas, I can post certain sections of code to help explain.
Here is code:
Class init {
...
ItModel itModel = new ItModel ();
JTable table = new JTable(itModel );
TableRendrend rend = new TableRend();
table.getColumn("it").setCellRenderer(rend);
}
class TableRend implements TableCellRenderer {
JButton itButton;
...
getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int columns){
if(itButton ==null){
itButton = new JButton (JButton)value.getIcon();
}
return itButton;
}
}
Class itModel extends AbstractTableModel{
JButton button;
...
public Object getValueAt(int rowIndex, intColumnIndex){
if(button==null){
button = new JButton( new ImageIcon(JFreeChartImage.getImage()));
}
return button
}
}
This all works except when double clicking on the JButton and it displays TEXT ex.
javax.Swing.JButton(0,0,...)
all field values instead of the the actual chart image that should be displayed
There are several issues with the code you posted, and too long to include them all in a comment.
You should not store Swing components in the model. The creation of the components is the task for the renderer
I do not believe you can click the button which is returned by the renderer. That button is not contained in the JTable which is displayed. Only an image/screenshot/stamp of the button is drawn on-screen, but it does not behave like a button. You would need an editor for that. Consult the JTable tutorial about the editors and renderers for more information

Adding a JScrollPane component to a JTable column

I'm trying to add scrolling capabilities to a certain column in my JTable. I've implemented a custom TableCellRenderer component and I can see the scroll pane inside the table just fine, but I am not able to scroll it. I've tried implementing TableCellEditor as well and didn't have any luck.
public Component getTableCellEditorComponent(JTable arg0, Object arg1,
boolean arg2, int arg3, int arg4) {
return scrollPane;
}
Does anyone have any ideas how to make those cells which contain a scrollPane scrollable?
With TableCellRenderer it's not possible to add any scrolling behaviour, as it does not receive any events and only draws the component.
It is possible - however - to accomplish this by using a custom TableCellEditor with getTableCellEditor being:
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
JTextArea area = new JTextArea();
area.setLineWrap(true);
area.setText((String) value);
JScrollPane pane = new JScrollPane(area);
return pane;
}
Additionally, you have to control the editing behaviour of your CellEditor. To make the cell editable and scrollable always, isCellEditable should look like this:
public boolean isCellEditable(EventObject anEvent) {
return true;
}
Personally, I find this solution to be more of a hack than anything, though.
Also, this should only be for testing. You really do have to implement a better editing behaviour in my opinion.
A Renderer just paints the cells. I believe you need to implement a TableCellEditor to scroll.
As an alternative, consider placing a single scroll pane in a separate container and updating it's view in your selection listener.

JEditorPane inside JScrollPane not resizing as needed

I am implementing a Comment box facility in my application which user can resize using mouse. This comment box contains a scrollpane which instead contains a JEditorPane in which user can insert comment. I have added the editor pane inside a scroll pane for the following reason:
auto scolling of jeditorpane
When the user resizes the comment box, I am setting the desired size for JScrollPane and the JEditorPane. When the user is increasing the size of the comment box, the size of these components are increasing as desired but when the size of the comment box is decreased, the size of the JEditorPane does not decrease even after setting the size. This leads to the scrollbars inside the scrollpane.
I tried using setPreferrredSize, setSize, setMaximumSize for JEditorPane. Still the size of the editor pane is not reducing. I tried calling revalidate() or updateUI() after the setting of size but no use.
I am using Java 1.4.2.
Please provide me some insight....
I realise this is long since answered, but for future reference all you need to do is override the getScrollableTracksViewportWidth() to always return true, eg.
JEditorPane pane = new JEditorPane() {
public boolean getScrollableTracksViewportWidth() {
return true;
}
};
panel.add(new JScrollPane(pane));
Actually it is possible, luiscubal. Here is how,
To the JScrollPane add a ComponentListener for resize events
public static void main(String...args) {
//our test frame
JFrame frame = new JFrame("JEditorPane inside JScrollPane resizing");
frame.setLayout(new BorderLayout());
//our editing pane
final JEditorPane editor = new JEditorPane();
//our simple scroll pane
final JScrollPane scroller = new JScrollPane(editor);
//NOTE: this is the magic that is kind of a workaround
// you can also implement your own type of JScrollPane
// using the JScrollBar and a JViewport which is the
// preferred method of doing something like this the
// other option is to create a JEditorPane subclass that
// implements the Scrollable interface.
scroller.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
editor.setSize(new Dimension(
scroller.getWidth()-20,
scroller.getHeight()-20));
}
});
//just use up the entire frame area.
frame.add(scroller, BorderLayout.CENTER);
//quick and dirty close event handler
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(320, 240); //something not too big
frame.setLocationRelativeTo(null); //centers window on screen
frame.setVisible(true); // normally done in a SwingUtilities.invokeLater
}
Look luiscubal it is possible. Don't be so quick to announce things in Java as not possible. The swing api is quiet flexible and can do a lot of the work for you. However, if you use JComponents in ways they weren't made to be used you will end up with problems and have two options.
subclass subclass subclass basically create your own component.
find a work around, like the above solution.
Decreasing the size of a JEditorPane in a JScrollPane and then reducing it, is not possible.
You may want to use a JTextArea instead.

Categories