I would make a little rft text editor in Java and I would have that the different kind of fonts are show in my combo box in that font. The reason is because the user can see that font.
I know that you can use a combo box item for C#. But I didn't know for Java.
Can anyone help me?
Edit:
Sounds like you need to implement a custom renderer for your combo box.
See the java tutorial here: http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html#renderer
i.e. Something like this (assuming the Objects in your combo box are Fonts):
class CustomRenderer implements ListCellRenderer
{
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = new JLabel();
label.setFont(((Font) value).deriveFont(12f));
label.setText(((Font) value).getFontName());
return label;
}
}
Custom Combo box for font selection in java
Here is code :
package stack;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
public class CustomComboBox {
JComboBox fontComboBox;
JFrame frame;
String fontName[];
Integer array[];
public CustomComboBox() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
fontName = ge.getAvailableFontFamilyNames();
array = new Integer[fontName.length];
for(int i=1;i<=fontName.length;i++) {
array[i-1] = i;
}
fontComboBox = new JComboBox(array);
ComboBoxRenderar renderar = new ComboBoxRenderar();
fontComboBox.setRenderer(renderar);
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(fontComboBox);
frame.pack();
frame.setVisible(true);
}
public class ComboBoxRenderar extends JLabel implements ListCellRenderer {
#Override
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
int offset = ((Integer)value).intValue() - 1 ;
String name = fontName[offset];
setText(name);
setFont(new Font(name,Font.PLAIN,20));
return this;
}
}
public static void main(String args[]) {
new CustomComboBox();
}
}
and preview of the code see the Image
:
Related
I am working on making the Arduino IDE fully accessible for people using access software. This means adding keyboard accessibility to two of the dialogs that currently do not work with access software under windows. The two dialogs are the Board Manager and the LibraryManager. If you want a real example of what I am posting you can get teh Arduino IDE on the Windows Store or download it on line. Just search for Arduino IDE and download the windows version. .
doing all that might be to much for most of you so I have created a more simple table that shows the same problem. If someone can help me understand how to add keyboard and focus access to the below Custom JTable and its custom column which is a JPanel I can work on fixing the Arduino IDE tables.
I understand that the Arduino IDE should probably be made into a
better table but I have yet to figure out a cleaner way to do what they are doing with these tables so I am trying to make what they have accessible.
So below is my problem table. It has two rows and two columsn. The
second column of each row is a panel of controls. I have borrowed
this code from some other stack posts and modified it to fit my
question. So if you think you have seen some of this code before that
is why. The problem is the code works for a mouse. At least I think
it does because I am blind and can not select the controls on the
second column because they can not get keyboard focus.
So Can someone out there help me figure out how to get keyboard focus
to move through this entire table. I have tried using focus
listeners, keyboard listeners, Focus Traversal policies, property
changes, and combinations between all of the above. I have taken out
my terrible attempts. Swing really should work without having to do
all this extra work but Java is what java is.
So if you are great at Java with swing please put away your mouse and run this
code and see if you can make the buttons activate without the mouse.
If you can and you can explain to me how to do it many blind users will
be in your debt.
Note that you should be able to Shift+Control+tab tot he table if the table is not the only control. On my sample it is. Then you should be able to arrow through the rows and columns and tab and shift+tab through the controls on the JPanel.
You can get the zip group of these files if you don't want to
put this all together yourself at this dropbox link:
https://www.dropbox.com/s/h4bdfu1mlo0jsvr/TableAccessTest.zip?dl=0
Here is the files. Each class has a comment with the file name before it. Again get the zip if you don't want to play block and copy.
//TableAccessTest.java
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
public class TableAccessTest extends JPanel
{
TableModel customRendererEditorTableModel = new TableModel();
JTable table;
public TableAccessTest()
{
setLayout(new BorderLayout());
table = new JTable(customRendererEditorTableModel);
table.setPreferredScrollableViewportSize(new Dimension(500, 600));
table.setRowSelectionAllowed(false);
table.setRowHeight(300);
table.getColumn("Custom JPanel").setCellRenderer(new CustomJPanelRenderer());
table.getColumn("Custom JPanel").setCellEditor(new CustomJPanelEditor());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Custom JPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new TableAccessTest();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
//CustomJPanel.java
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;
public class CustomJPanel extends JPanel
{
JPanel colorPanel = new JPanel(new BorderLayout());
JButton jButton = new JButton("Change Color");
JSlider jSlider = new JSlider(JSlider.VERTICAL);
JTextField jTextField = new JTextField("");
public CustomJPanel()
{
jButton.setOpaque(true);
jButton.setFocusable(true);
jTextField.setEditable(false);
jTextField.setFocusable(true);
setFocusable(true);
jButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(4);
switch (randomInt)
{
case (0):
colorPanel.setBackground(Color.BLUE);
jTextField.setText("blue");
break;
case (1):
colorPanel.setBackground(Color.BLACK);
jTextField.setText("black");
break;
case (2):
colorPanel.setBackground(Color.CYAN);
jTextField.setText("cyan");
break;
default:
colorPanel.setBackground(Color.GREEN);
jTextField.setText("green");
break;
}
}
});
jSlider.setOpaque(true);
setLayout(new BorderLayout());
add(colorPanel, BorderLayout.CENTER);
add(jButton, BorderLayout.SOUTH);
add(jTextField, BorderLayout.NORTH);
add(jSlider, BorderLayout.EAST);
}
}
//TableModel.java
import javax.swing.table.AbstractTableModel;
public class TableModel extends AbstractTableModel
{
private String[] columnNames =
{
"First Column",
"Custom JPanel",
};
private Object[][] data =
{
{"Foo", new CustomJPanel()},
{"Bar", new CustomJPanel()}
};
public int getColumnCount()
{
return columnNames.length;
}
public int getRowCount()
{
return data.length;
}
public String getColumnName(int col)
{
return columnNames[col];
}
public Object getValueAt(int row, int col)
{
return data[row][col];
}
public Class getColumnClass(int c)
{
return getValueAt(0, c).getClass();
}
public boolean isCellEditable(int row, int col)
{
return col >= 1;
}
public void setValueAt(Object value, int row, int col)
{
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
//CustomJPanelEditor.java
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
public class CustomJPanelEditor extends AbstractCellEditor implements TableCellEditor
{
CustomJPanel customJPanel;
public CustomJPanelEditor()
{
customJPanel = new CustomJPanel();
}
#Override
public java.awt.Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
customJPanel = (CustomJPanel) value;
return customJPanel;
}
#Override public Object getCellEditorValue()
{
return customJPanel;
}
}
//CustomJPanelRenderer.java
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
public class CustomJPanelRenderer implements TableCellRenderer
{
CustomJPanel rendererJPanel;
public CustomJPanelRenderer()
{
rendererJPanel = new CustomJPanel();
}
#Override
public java.awt.Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
rendererJPanel = (CustomJPanel) value;
return rendererJPanel;
}
}
I have a JComboBox that displays multiple text colors per line. I can't render it using HTML because the combo will contain large values (causing text wrapping). Instead, I created a custom renderer which extends JPanel (then I'm adding different JLabels to that panel which have different foreground/background colors).
In order to display the colors correctly, for each label I have to change setOpaque to true. This overrides the selected item's background color at the top as well:
Is there any way to prevent this behavior? Changing the JPanel's color doesn't change top's background color, but apparently its children JLabels do?
Renderer:
import java.awt.Color;
import java.awt.Component;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JList;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
public class CustomComboBoxRenderer extends JPanel implements ListCellRenderer {
private JLabel[] labels = { new JLabel(), new JLabel(), new JLabel() };
public CustomComboBoxRenderer() {
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
for (JLabel label : labels) {
label.setOpaque(true);
label.setVerticalAlignment(JLabel.CENTER);
add(label);
}
}
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
if(value != null) {
String valueString = value.toString();
if(valueString.contains("<red>")) {
int redStart = valueString.indexOf("<red>");
valueString = valueString.replace("<red>", "");
int redEnd = valueString.indexOf("</red>");
valueString = valueString.replace("</red>", "");
if(redStart > 0) {
labels[0].setText(valueString.substring(0, redStart));
}
labels[1].setText(valueString.substring(redStart, redEnd));
if(redEnd < valueString.length()) {
labels[2].setText(valueString.substring(redEnd, valueString.length()));
}
} else {
labels[0].setText(valueString);
labels[1].setText("");
labels[2].setText("");
}
}
if (isSelected) {
labels[0].setBackground(list.getSelectionBackground());
labels[1].setBackground(list.getSelectionBackground());
labels[2].setBackground(list.getSelectionBackground());
labels[0].setForeground(list.getSelectionForeground());
labels[1].setForeground(Color.RED);
labels[2].setForeground(list.getSelectionForeground());
} else {
labels[0].setBackground(list.getBackground());
labels[1].setBackground(list.getBackground());
labels[2].setBackground(list.getBackground());
labels[0].setForeground(list.getForeground());
labels[1].setForeground(Color.RED);
labels[2].setForeground(list.getForeground());
}
setBackground(list.getBackground());
return this;
}
}
To set part of the text to red, a simple tag is used:
String comboString = "TEST (<red>Red Text</red>) TEST";
Normally in situations like this, I set the opaque state only when item is selected
setOpaque(isSelected);
Well, I'm trying to render some components in the tables mentioned above. I know thats done with implementing a custom TableCellRenderer, and that works just fine in normal JTable, e.g. doing something like this:
import java.awt.Component;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
public class Test
{
public static void main(String[] argv)
{
String[] columnNames = {"First Name","Last Name","nr"};
Object[][] data = {{"Homer","Simpson","1"},{"Madge","Simpson","2"},{"Bart","Simpson","3"},
{"Lisa","Simpson","4"},};
DefaultTableModel model = new DefaultTableModel(data,columnNames);
JTable table = new JTable(model);
table.getColumnModel().getColumn(2).setCellRenderer(new TableCellRenderer(){
final JButton button = new JButton();
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
button.setText(value.toString());
return button;
}
});
JFrame f = new JFrame();
f.setSize(300,300);
f.add(new JScrollPane(table));
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
It also works with JIDE's Sortable- and AggregateTable, but as soon as I replace those tables with Xdev's, the component isn't rendered anymore, so it seems the CellRenderer isn't set properly, even though TableColumn.getCellRenderer() returns the correct class.
So does anyone know how to render a component in Xdev's tables?
Thanks in advance!
I am using a JTable and in order to change the format of numbers. I have extended the DefaultTableRenderer class.
In the method getTableCellRenderedComponent, I retrun a new JLabel with the proper format.
My problem is by doing this the rectangle (border) that underlines the cell which has the focus has disappeared.
Is there a way to get the default border displayed whenever a cell has the focus with my custom render?
in order to change the format of numbers. I have extended the DefaultTableRenderer class.
Check out Table Format Renderers for an easier way to customize the renderer when all you need to do is format the data. That is you should override the setValue(...) method instead of the getTableCellRenderer(...) method.
If you use DefaultTableRenderer you can call super() method and get Border from returned component. Try next example:
import java.awt.Component;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
public class TestFrame extends JFrame {
public TestFrame() {
init();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private void init() {
JTable t = new JTable(3,3);
t.getColumnModel().getColumn(0).setCellRenderer(getRenderer());
add(new JScrollPane(t));
}
private TableCellRenderer getRenderer() {
return new DefaultTableCellRenderer(){
private JLabel l = new JLabel();
{
l.setOpaque(true);
}
#Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
JComponent tableCellRendererComponent = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus,row, column);
l.setText(value == null ? "" : value.toString());
l.setBorder(tableCellRendererComponent.getBorder());
l.setBackground(tableCellRendererComponent.getBackground());
l.setForeground(tableCellRendererComponent.getForeground());
return l;
}
};
}
public static void main(String... s){
new TestFrame();
}
}
I have the following Java code:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JComboBox;
import javax.swing.JFrame;
public class EnumsRightVisible {
public void show() {
JFrame frame = new JFrame("Combo box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[] items = {"aaaaaaaaa__________zzzzzzzzz",
"aaaaaaaaa__________zzzzzzzzz",
"aaaaaaaaa__________zzzzzzzzz"};
JComboBox combo = new JComboBox(items);
combo.setPreferredSize(new Dimension(100,20));
frame.add(combo, BorderLayout.CENTER);
frame.setLocation(600, 100);
frame.pack();
frame.setVisible(true);
}
public static void main(String args[]) {
EnumsRightVisible enumsRightVisible = new EnumsRightVisible();
enumsRightVisible.show();
}
}
Running it you can see that the visible text is left oriented.
Please note that this code does not solve my problem (it aligns the text to the right, but only when the combo box is expanded):
((JLabel)comboBox.getRenderer()).setHorizontalAlignment(JLabel.RIGHT);
How can I display the right end of the text in the same window (...__zzzzzz)?
Thanks in advance!
Use a custom renderer that uses FontMetrics to measure the String's width and does the ellipsis (...) manually. More info here: http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html#renderer
Method 1
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ComboBoxDemo extends JFrame {
public ComboBoxDemo() {
JComboBox comboBox = new JComboBox();
((JLabel)comboBox.getRenderer()).setHorizontalAlignment(JLabel.RIGHT);
comboBox.addItem("Apple");
comboBox.addItem("Orange");
comboBox.addItem("Mango");
getContentPane().add(comboBox, "North");
setSize(200, 100);
this.setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ComboBoxDemo().setVisible(true);
}
}
Method 2 (Oviously, First is better)
import java.awt.Component;
import java.awt.ComponentOrientation;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
public class ComboBoxDemo extends JFrame {
public ComboBoxDemo() {
JComboBox comboBox = new JComboBox();
setListCellRendererOf(comboBox);
comboBox.addItem("Apple");
comboBox.addItem("Orange");
comboBox.addItem("Mango");
getContentPane().add(comboBox, "North");
setSize(200, 100);
this.setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void setListCellRendererOf(JComboBox comboBox) {
comboBox.setRenderer(new ListCellRenderer() {
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component component = new DefaultListCellRenderer()
.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
component.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
return component;
}
});
}
public static void main(String[] args) {
new ComboBoxDemo().setVisible(true);
}
}