Is it possible to get location of selected element in JList? I would like to get it to place JFrame just below clicked option.
You'll want to use JList#getCellBounds
int selectedIndex = list.getSelectedIndex();
Rectangle bounds = list.getSelectedBounds(selectedIndex, selectedIndex);
This will give you the location of the selected item within context to the JList, you'll need to translate this to screen space...
Point p = bounds.getLocation();
SwingUtilities.convertPointToScreen(p, list);
You may also want to take a look at The Use of Multiple JFrames: Good or Bad Practice?
For example...
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class List {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new List();
}
public List() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
final JFrame selected = new JFrame("Selected");
selected.add(new JLabel("Here I am"));
selected.pack();
DefaultListModel model = new DefaultListModel();
for (int index = 0; index < 1000; index++) {
model.addElement("#" + index);
}
final JList list = new JList(model);
list.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
int index = list.getSelectedIndex();
Rectangle bounds = list.getCellBounds(index, index);
Point p = bounds.getLocation();
p.y += bounds.height;
SwingUtilities.convertPointToScreen(p, list);
p.x -= selected.getWidth();
selected.setLocation(p);
selected.setVisible(true);
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(list));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
You can use indexToLocation() method of JList, for example:
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class TestFrame extends JFrame {
public TestFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
init();
pack();
setVisible(true);
}
private void init() {
final JPopupMenu menu = new JPopupMenu("test");
menu.add(new JMenuItem("1"));
final JList<String> list = new JList<String>(new String[]{"1","2","3"});
list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
int selectedIndex = list.getSelectedIndex();
if(selectedIndex != -1){
Point indexToLocation = list.indexToLocation(selectedIndex);
Rectangle cellBounds = list.getCellBounds(selectedIndex, selectedIndex);
menu.show(list, indexToLocation.x, indexToLocation.y+cellBounds.height);
}
}
});
add(list);
}
public static void main(String... strings) {
new TestFrame();
}
}
Related
I need to display a user-inputted number of tabs (JTabbedPane) (with the same initial content, but the ability to individually change the content), is there a way to create these components procedurally so I don't have to know how many there will be before the user input?
Here is an example of change number of tabse depended on user input:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TabbedPaneTest3 implements Runnable {
private final JTabbedPane tabber = new JTabbedPane();
public static void main(String[] args) {
SwingUtilities.invokeLater(new TabbedPaneTest3());
}
#Override
public void run() {
final JSpinner spinner = new JSpinner(new SpinnerNumberModel(3, 1, 10, 1));
spinner.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
Object val = spinner.getValue();
if (val instanceof Number) {
updateTabsNumber((Number) val);
}
}
});
updateTabsNumber(3);
JFrame frm = new JFrame("Tab Pane");
JPanel panel = new JPanel();
panel.add(new JLabel("Number of tabs: "));
panel.add(spinner);
frm.add(panel, BorderLayout.NORTH);
frm.add(tabber);
frm.setSize(600, 400);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private void updateTabsNumber(Number val) {
int count = val.intValue();
tabber.removeAll();
for (int i = 0; i < count; i++) {
String text = "Tab " + (i + 1);
JTextArea area = new JTextArea(10, 30);
area.setText("Initial text for tab: " + (i + 1));
tabber.addTab(text, new JScrollPane(area));
}
}
}
http://prntscr.com/9jhrwa "How the GUI looks"
public class Okno1 extends javax.swing.JFrame {
static Konto[]konto;
static DefaultListModel listModel;
static int indexKonta;
public Okno1() {
initComponents();
napolniKonto();
jScrollPane1.setVisible(false);
button_potrdiKonto.setVisible(false);
}
here I fill my array with Objects and add them to DefaultListModel, also I create a new list with the mentioned DefaultListModel
listModel=new DefaultListModel();
list_konto.setModel(listModel);
konto=new Konto[4];
konto[0]=new Konto("10000/20000", "Test konto primer1");
konto[1]=new Konto("20000/30000", "Test konto primer2");
konto[2]=new Konto("50000/60000", "Test konto primer3");
konto[3]=new Konto("30000/50000", "Test konto primer4");
for (int i = 0; i < konto.length; i++) {
listModel.addElement(konto[i].getID()+" | "+konto[i].getOpis());
}
list_konto=new JList(listModel);
jScrollPane1.repaint();
}
Here I show the jScrollPanel when this button is pressed, I also show the button which must be pressed if I want to get the index of the selected element in the JList displayed
private void button_prikaziKontoActionPerformed(java.awt.event.ActionEvent evt) {
jScrollPane1.setVisible(true);
button_potrdiKonto.setVisible(true);
//revalidate();
//repaint();
}
Here I press a button and it should get me the index of the selected item, but it keeps giving me -1 and it doesn't matter if an item on the JList is selected or is not
private void button_potrdiKontoActionPerformed(java.awt.event.ActionEvent evt) {
//indexKonta=list_konto.getSelectedIndex();
text_opisKonta.setText(Integer.toString(list_konto.getSelectedIndex()));
}
It's not clear where your code is going awry. This compete example may allow you to study the problem in isolation. Also consider adding a ListSelectionListener to see the effect.
myList.addListSelectionListener((ListSelectionEvent e) -> {
myLabel.setText(getSelectionIndex());
});
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionEvent;
/** #see http://stackoverflow.com/a/34497773/230513 */
public class Test extends JPanel {
private final String[] values = {"Value1", "Value2", "Value3", "Value4"};
private final JList myList = new JList(values);
private final JLabel myLabel = new JLabel();
public Test() {
myList.setSelectedIndex(values.length - 1);
myLabel.setText(getSelectionIndex());
this.add(myList);
this.add(myLabel);
this.add(new JButton(new AbstractAction("Show Selected Index") {
#Override
public void actionPerformed(ActionEvent e) {
myLabel.setText(getSelectionIndex());
}
}));
}
private String getSelectionIndex() {
return String.valueOf(myList.getSelectedIndex());
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Test());
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
});
}
}
don't use static variables
always to test if (list.getSelectedIndex() > -1) {
use ListSelectionListener for JList, by always testing if (list.getSelectedIndex() > -1) {
for example (without using ListSelectionListener)
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
public class JListAndSelection {
private JFrame frame = new JFrame();
private DefaultListModel listModel = new DefaultListModel();
private JList list = new JList(listModel);
private JScrollPane scrollPane = new JScrollPane(list);
private JLabel label = new JLabel("nothing is selected");
private JButton button1 = new JButton("print me selected value");
public JListAndSelection() {
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (list.getSelectedIndex() > -1) {
label.setText((String) list.getSelectedValue());
} else {
label.setText("nothing is selected");
}
}
});
listModel.addElement("10000/20000 - Test konto primer1");
listModel.addElement("20000/30000 - Test konto primer2");
listModel.addElement("50000/60000 - Test konto primer3");
listModel.addElement("30000/50000 - Test konto primer4");
list.setVisibleRowCount(5);
frame.setTitle("JFrame");
frame.add(label, BorderLayout.NORTH);
frame.add(scrollPane, BorderLayout.CENTER);
frame.add(button1, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new JListAndSelection();
});
}
}
i want to get the line of the current mousePosition in an JTextArea.
I cant find a method to get the line using the coordinates which i receive from the MouseMotionAdapter -> event.getPoint();.
Has anyone an idea, how i could do it?
Here is simple example with help of viewToModel() and getLineOfOffset() methods:
import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
public class TestFrame extends JFrame {
private JTextArea area;
private JLabel l;
public TestFrame() {
init();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private void init() {
area = new JTextArea(5,5);
area.addMouseMotionListener(getListener());
l = new JLabel(" ");
add(new JScrollPane(area));
add(l,BorderLayout.SOUTH);
}
private MouseMotionListener getListener() {
return new MouseMotionListener() {
#Override
public void mouseMoved(MouseEvent e) {
int viewToModel = area.viewToModel(e.getPoint());
if(viewToModel != -1){
try {
l.setText("line: "+(1+area.getLineOfOffset(viewToModel)));
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
}
#Override
public void mouseDragged(MouseEvent e) {
}
};
}
public static void main(String args[]) {
new TestFrame();
}
}
I wanted to know how to set an image to a JTextField if this is transparent, or how to make my JTextField look like this:
Here's how I make my field transparent, but I can't set its background image:
//Step 1: Remove the border line to make it look like a flat surface.
field.setBorder(BorderFactory.createLineBorder(Color.white, 0));
//Step 2: Set the background color to null to remove the background.
field.setBackground(null);
All Swing components have a concept of transparency, which is controlled via the use of opaque property. Setting the background to null tents to rest the background color of the field to it's UI default.
Having said that, some components can ignore this (partially or completely). In these case we can cheat...
In the following example, set the field transparent via the opaque property, this is important, as the RepaintManager will not paint areas behind components unless they are transparent, and use a fully transparent background color.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestTextField {
public static void main(String[] args) {
new TestTextField();
}
public TestTextField() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextField field = new JTextField(20);
field.setBackground(new Color(0, 0, 0, 0));
field.setOpaque(false);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.RED);
frame.setLayout(new GridBagLayout());
frame.add(field);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Updated based on comments...
This is a very specific example designed to provide a direct answer to the presented problem. Basically, what this does is creates a custom border and uses an Image to render the "border"
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;
public class TestTextField {
public static void main(String[] args) {
new TestTextField();
}
public TestTextField() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextField field = new JTextField(20);
try {
BufferedImage img = ImageIO.read(getClass().getResource("/FieldBorder.png"));
field.setBorder(new ImageBorder(img, 8, 6));
} catch (IOException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(field);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ImageBorder implements Border {
private BufferedImage img;
private int bottomMargin;
private int leftMargin;
public ImageBorder(BufferedImage img, int leftMargin, int bottomMargin) {
this.img = img;
this.bottomMargin = bottomMargin;
this.leftMargin = leftMargin;
}
#Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
g.drawImage(img, x, y + height - img.getHeight(), c);
}
#Override
public Insets getBorderInsets(Component c) {
return new Insets(0, leftMargin, bottomMargin, 0);
}
#Override
public boolean isBorderOpaque() {
return false;
}
}
}
Now, this could also be done using custom painting within the custom Border instead, but was quicker this way ;)
Another option...
Is to simply use a JPanel and add the field and a JLabel holding the border outline together, for example...
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
public class TestTextField {
public static void main(String[] args) {
new TestTextField();
}
public TestTextField() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextField field = new JTextField(20);
field.setBorder(null);
JPanel fieldPane = new JPanel(new GridBagLayout());
fieldPane.setBackground(Color.WHITE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(0, 8, 0, 0);
fieldPane.add(field, gbc);
try {
BufferedImage img = ImageIO.read(getClass().getResource("/FieldBorder.png"));
gbc.insets = new Insets(0, 0, 0, 0);
fieldPane.add(new JLabel(new ImageIcon(img)), gbc);
} catch (IOException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(fieldPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
But this will come down to needs and requirements...
Text field with a background
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.Document;
public class TextFieldBackground {
public static void main(String[] args) {
new TextFieldBackground();
}
public TextFieldBackground() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
TextFieldWithBackground field = new TextFieldWithBackground(40);
try {
field.setBackgroundImage(ImageIO.read(getClass().getResource("/clouds.jpg")));
} catch (IOException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(field);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TextFieldWithBackground extends JTextField {
private BufferedImage bg;
public TextFieldWithBackground() {
}
public TextFieldWithBackground(String text) {
super(text);
}
public TextFieldWithBackground(int columns) {
super(columns);
}
public TextFieldWithBackground(String text, int columns) {
super(text, columns);
}
public TextFieldWithBackground(Document doc, String text, int columns) {
super(doc, text, columns);
}
public void setBackgroundImage(BufferedImage bg) {
this.bg = bg;
setOpaque(bg == null);
repaint();
}
#Override
protected void paintComponent(Graphics g) {
if (bg != null) {
int x = 0;
int y = (getHeight() - bg.getHeight()) / 2;
while (x < getWidth()) {
g.drawImage(bg, x, y, this);
x += bg.getWidth();
}
}
super.paintComponent(g);
}
}
}
I have a button that inserts an unordered list item into a JTextPane. However, when I click on the button to insert a list item, two bullets are inserted instead of one. One bullet is inserted only during the first time insertion.
I cut out the functionality from my application and pasted the code into a small SSCCE (below) and the problem remains. Does anyone have any idea as to what might be happening here?
[The problem has been solved, below is the complete solved code. There are two ways to do this, refer to the functionality in the show and the bullets button]
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.ElementIterator;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
public class Main {
private static Button2 show = new Button2 ("Show");
private static LIButton bullets = new LIButton("Bullets", HTML.Tag.UL);
private static JEditorPane pane = new JEditorPane();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
create();
}
});
}
private static void create() throws HeadlessException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pane.setPreferredSize(new Dimension(300, 300));
pane.setContentType("text/html");
frame.add(pane, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.add(bullets);
panel.add(show);
frame.add(panel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class LIButton extends JButton {
static final String LI_HTML = "<HTML><BODY><UL><LI></LI></UL></BODY></HTML>";
public LIButton(String name, HTML.Tag parent) {
super(new HTMLEditorKit.InsertHTMLTextAction(
name, LI_HTML, HTML.Tag.UL, HTML.Tag.LI, HTML.Tag.BODY, HTML.Tag.UL));
}
}
static class Button2 extends JButton implements ActionListener {
static final String LI_HTML = "<HTML><BODY><UL><LI></LI></UL></BODY></HTML>";
public Button2(String name) {
super(name);
this.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent ae) {
HTMLDocument doc = (HTMLDocument) pane.getDocument();
HTMLEditorKit kit = (HTMLEditorKit) pane.getEditorKit();
try {
kit.insertHTML(doc, doc.getLength() - 1, LI_HTML, 0, 1, null);
} catch (BadLocationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The example below seems to work.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
public class Main {
private static LIButton bullets = new LIButton("Bullets", HTML.Tag.UL);
private static JTextPane pane = new JTextPane();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
create();
}
});
}
private static void create() throws HeadlessException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pane.setPreferredSize(new Dimension(300, 300));
pane.setContentType("text/html");
pane.setText("<HTML><BODY><UL></UL></BODY></HTML>");
frame.add(pane, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.add(bullets);
frame.add(panel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class LIButton extends JButton {
static final String LI_HTML = "<LI>item</LI>";
public LIButton(String name, HTML.Tag parent) {
super(new HTMLEditorKit.InsertHTMLTextAction(
name, LI_HTML, parent, HTML.Tag.LI));
}
}
}