I am writing a simple text based chat application using applets in java, which consists of few components & one of them is my Jlist which provides list of online users at that particular point of time.
What i want is that i need to set a small picture besides online user name in Jlist.
Does anyone have any idea based on this. Please feel free to ask if you have any questions.
Thanks,
Puneet
The JList documentation has an example that loads icons into the JList. You should be able to use this to insert your small pictures into the JList.
http://docs.oracle.com/javase/6/docs/api/javax/swing/JList.html
Here is the relevant code from that link:
// Display an icon and a string for each object in the list.
class MyCellRenderer extends JLabel implements ListCellRenderer {
final static ImageIcon longIcon = new ImageIcon("long.gif");
final static ImageIcon shortIcon = new ImageIcon("short.gif");
// This is the only method defined by ListCellRenderer.
// We just reconfigure the JLabel each time we're called.
public Component getListCellRendererComponent(
JList list, // the list
Object value, // value to display
int index, // cell index
boolean isSelected, // is the cell selected
boolean cellHasFocus) // does the cell have focus
{
String s = value.toString();
setText(s);
setIcon((s.length() > 10) ? longIcon : shortIcon);
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setEnabled(list.isEnabled());
setFont(list.getFont());
setOpaque(true);
return this;
}
}
myList.setCellRenderer(new MyCellRenderer());
Assuming your JList contains usernames, you could put your usernames in a HashMap
setIcon(userHashMap.get(s));
If your JLIst is actually store other parts than just the username (dynamic components such as status, group name, etc.) you may need to parse out the username from the String passed into the value object.
Related
So I have a class called Note and I need to put every Note inside a JComboBox.
Each Note has a String id and a String title. The title is being shown to the user, and the id is being used in the backend.
I've written a custom renderer to make this work, but I am getting compiler error: error: Note cannot be converted to String
Here is the code:
//Inside of the GUI class
cmbNotes.setRenderer(new NoteListCellRenderer());
//Populate combo box with the title of each note
NoteManager.notes.forEach((id, note) -> { //For-each loop
if (!note.isOpen()) {
cmbNotes.addItem(note); //ERROR: Note cannot be converted to String
}
});
Here is my custom renderer:
//In the same file as GUI, but outside of the GUI class
class NoteListCellRenderer extends DefaultListCellRenderer {
#Override
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
if (value instanceof Note) {
value = ((Note) value).getTitle();
}
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
return this;
}
}
Thank you Riann Nel for helping me to solve this problem.
I had created the JComboBox through the design, not through code.
The design by default sets the Type Parameters to String so I went in the design and clicked on the code section on the right then changed the Type Parameters to <Note>.
I also had to add a default constructor in my Note class.
I have the following problem: i currently have a few classes representing various plants and animals, which all have base class "Organism", they are part of a world (another class, which contains a "2D" container of Organisms or empty fields - kinda like a 2D map of a world). Only 1 organism can occupy a world slot at the same time.
What i want is to draw a map of this world. In order to do this i have created a JTable, which uses world's 2D container as a data source. Now the problem is, i don't know how to make the JTable use class's own methods in order to draw cells.
Each class has it's method which returns an image representing it:
#Override public ImageIcon drawing(){
return new ImageIcon("Guarana.png");
}
my table has following components available:
private String[] columnNames;
private Object[][] data;
I've created my own table model (following the tutorial here: https://docs.oracle.com/javase/tutorial/uiswing/components/table.html)
So the creation of table looks like this:
model = new MyTableModel(testowyString, organizmy);
JTable table = new JTable(model);
table.setFillsViewportHeight(true);
table.setDefaultRenderer(Organizm.class, new IconRenderer());
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBounds(210, 0, 780, 900);
add(scrollPane);
As you can see i have tried to create my own IconRenderer (but for some reason the JTable still doesn't draw the icons):
public class IconRenderer extends DefaultTableCellRenderer {
ImageIcon sheepIcon = new ImageIcon("Owca.png");
ImageIcon wolfIcon = new ImageIcon("Wilk.png");
ImageIcon mouseIcon = new ImageIcon("Mysz.png");
ImageIcon chickenIcon = new ImageIcon("Kurka.png");
ImageIcon turtleIcon = new ImageIcon("Zolw.png");
ImageIcon grassIcon = new ImageIcon("Trawa.png");
ImageIcon guaranaIcon = new ImageIcon("Guarana.png");
ImageIcon emptyIcon = new ImageIcon("Pusty.png");
public IconRenderer() { super(); }
public void setValue(Organizm organizm) {
setIcon((organizm == null) ? ikonkaPusty : organizm.rysowanie());
}
}
(yes, the icons here are a part of my old code, when each class didn't return it's icon)
To sum up: i want to make it so when JTable draws a map it draws an icon using an existing method of a class which is linked to cell.
Instead of overriding setValue() you need to override getTableCellRendererComponent() and call setIcon() from there. The value argument will be the Organizm that is the table cell's value, so you can do this:
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Organizm o = (Organizm) value;
setIcon((organizm == null) ? ikonkaPusty : organizm.rysowanie());
return this;
}
I'm assuming that organizm.rysowanie() returns the ImageIcon. Although if that's true, then your setValue() implementation probably should have worked. Another thought I have is to change your setValue() signature to public void setValue(Object value) and cast value in the method like in my example above. This would avoid method overloading issues that would result in calling the setValue() method with an Object argument instead of your setValue() method with the Organizm argument.
So i am working with a JTable, It has Columns A-K. with A and B being the only editable ones. If someone edits an empty row in A, I make an API call to get B then i make a DB call to get all rows where B exists.If someone edits an empty row in B, i make the same call as the will be retrieved from the DB for that row as well. The call returns 0-N rows. If 0 rows were returned, I change the values of all row except B to N/A otherwise i populate the rows using the data.Once populated, i make all columns non-editable. The DB call occurs in its own thread as once the call is return i create my own record object which I add to the tablemodel.
I have my own TableModel and a TableModelListener to keep the data and handle changes in values.
Here is my issue. I am using TableCellRenderer and using the cellrenderer to see if the value was changed, if so then i make the calls and populate as needed. When a large number of rows is being pulled from DB, it takes a while to load and making all that records so I tried to use a ProgressBar to show the user that the screen isn't just frozen, it is progressing and by how much. However the frame that comes up is blank and nothing gets displayed. I get the feeling i am doing something either improperly or missing something.Any help much appreciated.
some code to understand what i am talking about
public class MyPanel extends JPanel {
private JTable myTable;
private MyTableModel tm;
//OTHER FIELDS
public static void createPanel() {
tm = new MyTableModel(columnnames);
myTable = new JTable(tm);
TableColumn account = myTable.getColumnModel().getColumn(
MyTableModel.ACCOUNT_INDEX);
account.setCellRenderer(new MyTableRenderer(
MyTableModel.ACCOUNT_INDEX));
}
}
public class MyTableRenderer extends DefaultTableCellRenderer{
protected int interactiveColumn;
public MyTableRenderer(int interactiveColumn) {
this.interactiveColumn = interactiveColumn;
}
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component c = super.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
if (column == interactiveColumn && hasFocus) {
//DO DB and API CALLS HERE
//IF DB CALL DISPLAY A NEW FRAME WITH PROGRESSBAR
}
return c;
}
}
Sorry for formatting issues
Use SwingWorker, which allows you to update your TableModel as you examine your result set.
Addendum: Don't try to update the TableModel from the renderer. You can update the model when your implementation of CellEditor has concluded, by starting a suitable worker in getCellEditorValue(). In that way, the revised data will be available when the renderer is next invoked for any modified cell(s). This related example outlines the approach.
Addendum: getCellEditorValue() is invoked after editing has concluded, but starting the worker in setValueAt() offers more reliable access to the target row and column.
I have three jLists in my class frmMain. I have created a class called ListActions. The code below is working for one jList. It returns the value clicked for one jList.
How do I distinguish between the three other jList? Or do I need to create a seperate class for each listener?
I need to perform an action based on which jList was clicked. I attempted to see if I could access the variable name of the jList that was clicked, but couldn't find a way to do this...
class ListActions implements ListSelectionListener {
public void valueChanged(ListSelectionEvent evt) {
if (!evt.getValueIsAdjusting()) {
JList list = (JList) evt.getSource();
int iSelectedDatabase = list.getSelectedIndex();
Object objSelectedDatabase = list.getModel().getElementAt(iSelectedDatabase);
String sSelectedDatabase = objSelectedDatabase.toString();
JOptionPane.showConfirmDialog(null, sSelectedDatabase);
}
}
}
Thanks,
- Jason
JList inherits from Component.
Therefore, you can use the getName() method to get the name of your Component and know which one has been called.
I have a JComboBox and have 10 string items added in it.
I want to assign different colors to each item.
How i can achive this?
Please help.
The example in Chandru's answer looks like a lot of code so I can understand why you're asking for an easier solution. However, if you subclass DefaultListCellRenderer a lot of the work is done for you, as this renderer is a subclass of JLabel.
JList list = ... // Create JList
// Install custom renderer.
list.setCellRenderer(new DefaultListCellRenderer() {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
// Request superclass to render the JLabel.
Component ret = super.getListCellRenderer(list, value, index, isSelected, cellHasFocus);
// Now conditionally override background if cell isn't selected.
if (!isSelected) {
String s = String.valueOf(value);
if (s.equals("Foo")) {
ret.setBackground(Color.RED);
} else {
ret.setBackground(Color.GREEN);
}
}
return ret;
}
});
You must use a custom list cell renderer. Look into this how-to for an example.
You must implement a new ListCellRenderer ,which will be used by your combobox, through setRenderer, to render properly your objects.
You can extend BasicComboBoxRenderer to avoid reconding everything.