|
|
Строка 1: |
Строка 1: |
- | __TOC__
| |
| | | |
- | Swing engineers created the Swing toolkit implementing a modified Model View Controller design pattern.
| |
- | This enables efficient handling of data and using pluggable look and feel at runtime.
| |
- |
| |
- | The traditional MVC pattern divides an application into three parts. A model, a view and a cotroller.
| |
- | The model represents the data in the application. The view is the visual representation of the data. And finally the
| |
- | controller processes and responds to events, typically user actions, and may invoke changes on the model.
| |
- | The idea is to separate the data access and business logic from data presentation and user interaction, by introducing an intermediate component: the controller.
| |
- |
| |
- | The Swing toolkit uses a modified MVC design pattern. The Swing has single <b>UI object</b> for both the view and the controller.
| |
- | This modified MVC is sometimes called a <b>separable model architecture</b>.
| |
- |
| |
- | In the Swing toolkit, every component has it's model. Even the basic ones like buttons. There are two kinds of models in Swing toolkit.
| |
- |
| |
- | * state models
| |
- | * data models
| |
- |
| |
- | The state models handle the state of the component. For example the model keeps track whether the component is selected or pressed. The data models handle data, they work with. A list component keeps a list of items, it is displaying.
| |
- |
| |
- | For Swing developer it means, that we often need to get a model instance in order to manipulate the data in the component.
| |
- | But there are exceptions. For convenience, there are some methods that return data without the model.
| |
- |
| |
- | <source lang="java">
| |
- | public int getValue() {
| |
- | return getModel().getValue();
| |
- | }
| |
- | </source>
| |
- |
| |
- | For example the <b>JSlider</b> component.
| |
- | The developer does not need to work with the model directly. Instead, the access to the model is done behind the scenes.
| |
- | It would be an overkill to work with models directly in such simple situations. Because of this, the Swing tookit provides some convenience methods like the previous one.
| |
- |
| |
- | To query the state of the model, we have two kinds of notifications.
| |
- |
| |
- | <ul style="list-style-image: url(../images/square.png);">
| |
- | <li>lightweight notification</li>
| |
- | <li>stateful notification</li>
| |
- |
| |
- | </ul>
| |
- |
| |
- | The lightweight notification uses a <b>ChangeListener</b> class. We have only one single event
| |
- | (<b>ChangeEvent)</b>
| |
- | for all notifications coming from the component. For more complicated components, the stateful notification is used.
| |
- | For such notifications, we have different kinds of events. For example the <b>ListSelectionEvent</b>.
| |
- |
| |
- | If we do not set a model for a component, a default one is created. For example the button component has
| |
- | <b>DefaultButtonModel</b> model
| |
- |
| |
- | <source lang="java">
| |
- | public JButton(String text, Icon icon) {
| |
- | // Create the model
| |
- | setModel(new DefaultButtonModel());
| |
- |
| |
- | // initialize
| |
- | init(text, icon);
| |
- | }
| |
- | </source>
| |
- |
| |
- | If we look at the JButton.java source file, we find out, that the default model is created at the construction of the component.
| |
- |
| |
- | == ButtonModel ==
| |
- |
| |
- | The model is used for various kinds of buttons like push buttons, check boxes, radio boxes and for menu items.
| |
- | The following example illustrates the model for a <b>JButton</b>. We can manage only the state of the button, because no data can be associated with a push button.
| |
- |
| |
- | <source lang="java">
| |
- | import java.awt.event.ActionEvent;
| |
- | import java.awt.event.ActionListener;
| |
- |
| |
- | import javax.swing.DefaultButtonModel;
| |
- | import javax.swing.JButton;
| |
- | import javax.swing.JCheckBox;
| |
- | import javax.swing.JFrame;
| |
- | import javax.swing.JLabel;
| |
- | import javax.swing.JPanel;
| |
- | import javax.swing.event.ChangeEvent;
| |
- | import javax.swing.event.ChangeListener;
| |
- |
| |
- |
| |
- | public class ButtonModel extends JFrame {
| |
- |
| |
- | private JButton ok;
| |
- | private JLabel enabled;
| |
- | private JLabel pressed;
| |
- | private JLabel armed;
| |
- |
| |
- | public ButtonModel() {
| |
- |
| |
- | setTitle("ButtonModel");
| |
- |
| |
- | JPanel panel = new JPanel();
| |
- | panel.setLayout(null);
| |
- |
| |
- | ok = new JButton("ok");
| |
- | JCheckBox cb = new JCheckBox("Enabled", true);
| |
- |
| |
- | ok.setBounds(40, 30, 80, 25);
| |
- | ok.addChangeListener(new ChangeListener() {
| |
- | public void stateChanged(ChangeEvent e) {
| |
- |
| |
- | DefaultButtonModel model = (DefaultButtonModel) ok.getModel();
| |
- | if (model.isEnabled())
| |
- | enabled.setText("Enabled: true");
| |
- | else
| |
- | enabled.setText("Enabled: false");
| |
- |
| |
- | if (model.isArmed())
| |
- | armed.setText("Armed: true");
| |
- | else
| |
- | armed.setText("Armed: false");
| |
- |
| |
- | if (model.isPressed())
| |
- | pressed.setText("Pressed: true");
| |
- | else
| |
- | pressed.setText("Pressed: false");
| |
- | }
| |
- |
| |
- | });
| |
- |
| |
- | cb.addActionListener(new ActionListener() {
| |
- |
| |
- | public void actionPerformed(ActionEvent e) {
| |
- | if (ok.isEnabled())
| |
- | ok.setEnabled(false);
| |
- | else
| |
- | ok.setEnabled(true);
| |
- | }
| |
- | });
| |
- |
| |
- | cb.setBounds(180, 30, 100, 25);
| |
- |
| |
- | enabled = new JLabel("Enabled: true");
| |
- | enabled.setBounds(40, 90, 90, 25);
| |
- | pressed = new JLabel("Pressed: false");
| |
- | pressed.setBounds(40, 120, 90, 25);
| |
- | armed = new JLabel("Armed: false");
| |
- | armed.setBounds(40, 150, 90, 25);
| |
- |
| |
- | panel.add(ok);
| |
- | panel.add(cb);
| |
- | panel.add(enabled);
| |
- | panel.add(pressed);
| |
- | panel.add(armed);
| |
- |
| |
- | add(panel);
| |
- |
| |
- | setSize(350, 250);
| |
- | setLocationRelativeTo(null);
| |
- | setDefaultCloseOperation(EXIT_ON_CLOSE);
| |
- | setVisible(true);
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | new ButtonModel();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | In our example, we have a button, check box and three labels. The labels represent three properties of the button.
| |
- | Whether it is pressed, disabled or armed.
| |
- |
| |
- | <source lang="java">
| |
- | ok.addChangeListener(new ChangeListener() {
| |
- | </source>
| |
- |
| |
- | We use a lightweight <b>ChangeListener</b> to listen for button state changes.
| |
- |
| |
- | <source lang="java">
| |
- |
| |
- | DefaultButtonModel model = (DefaultButtonModel) ok.getModel();
| |
- | </source>
| |
- |
| |
- | Here we get the default button model.
| |
- |
| |
- | <source lang="java">
| |
- | if (model.isEnabled())
| |
- | enabled.setText("Enabled: true");
| |
- | else
| |
- | enabled.setText("Enabled: false");
| |
- | </source>
| |
- |
| |
- | We query the model, whether the button is enabled or not. We update the label accordingly.
| |
- |
| |
- | <source lang="java">
| |
- | if (ok.isEnabled())
| |
- | ok.setEnabled(false);
| |
- | else
| |
- | ok.setEnabled(true);
| |
- | </source>
| |
- |
| |
- | The check box enables or disables the button. To enable the ok button, we call the <b>setEnable()</b>
| |
- | method. So we change the state of the button. Where is the model? The answer lies in the AbstractButton.java file.
| |
- |
| |
- | <source lang="java">
| |
- | public void setEnabled(boolean b) {
| |
- | if (!b && model.isRollover()) {
| |
- | model.setRollover(false);
| |
- | }
| |
- | super.setEnabled(b);
| |
- | model.setEnabled(b);
| |
- | }
| |
- |
| |
- | </source>
| |
- |
| |
- | The answer is, that internally, we the Swing toolkit works with a model. The <b>setEnable()</b> is another convenience method for programmers.
| |
- |
| |
- | [[image: java_swing_buttonmodel.png | center]]
| |
- |
| |
- | == Custom ButtonModel ==
| |
- |
| |
- | In the previous example, we used a default button model. In the following code example we will use our own
| |
- | button model.
| |
- |
| |
- | <source lang="java">
| |
- | import java.awt.event.ActionEvent;
| |
- | import java.awt.event.ActionListener;
| |
- |
| |
- | import javax.swing.ButtonModel;
| |
- | import javax.swing.DefaultButtonModel;
| |
- | import javax.swing.JButton;
| |
- | import javax.swing.JCheckBox;
| |
- | import javax.swing.JFrame;
| |
- | import javax.swing.JLabel;
| |
- | import javax.swing.JPanel;
| |
- |
| |
- |
| |
- | public class ButtonModel2 extends JFrame {
| |
- |
| |
- | private JButton ok;
| |
- | private JLabel enabled;
| |
- | private JLabel pressed;
| |
- | private JLabel armed;
| |
- |
| |
- | public ButtonModel2() {
| |
- |
| |
- | setTitle("ButtonModel");
| |
- |
| |
- | JPanel panel = new JPanel();
| |
- | panel.setLayout(null);
| |
- |
| |
- | ok = new JButton("ok");
| |
- | JCheckBox cb = new JCheckBox("Enabled", true);
| |
- |
| |
- | ok.setBounds(40, 30, 80, 25);
| |
- |
| |
- | cb.addActionListener(new ActionListener() {
| |
- |
| |
- | public void actionPerformed(ActionEvent e) {
| |
- | if (ok.isEnabled())
| |
- | ok.setEnabled(false);
| |
- | else
| |
- | ok.setEnabled(true);
| |
- | }
| |
- | });
| |
- |
| |
- | cb.setBounds(180, 30, 100, 25);
| |
- |
| |
- | enabled = new JLabel("Enabled: true");
| |
- | enabled.setBounds(40, 90, 90, 25);
| |
- | pressed = new JLabel("Pressed: false");
| |
- | pressed.setBounds(40, 120, 90, 25);
| |
- | armed = new JLabel("Armed: false");
| |
- | armed.setBounds(40, 150, 90, 25);
| |
- |
| |
- | ButtonModel model = new DefaultButtonModel() {
| |
- | public void setEnabled(boolean b) {
| |
- | if (b)
| |
- | enabled.setText("Pressed: true");
| |
- | else
| |
- | enabled.setText("Pressed: false");
| |
- |
| |
- | super.setEnabled(b);
| |
- | }
| |
- |
| |
- | public void setArmed(boolean b) {
| |
- | if (b)
| |
- | armed.setText("Armed: true");
| |
- | else
| |
- | armed.setText("Armed: false");
| |
- |
| |
- | super.setArmed(b);
| |
- | }
| |
- |
| |
- | public void setPressed(boolean b) {
| |
- | if (b)
| |
- | pressed.setText("Pressed: true");
| |
- | else
| |
- | pressed.setText("Pressed: false");
| |
- |
| |
- | super.setPressed(b);
| |
- | }
| |
- |
| |
- | };
| |
- |
| |
- | ok.setModel(model);
| |
- |
| |
- | panel.add(ok);
| |
- | panel.add(cb);
| |
- | panel.add(enabled);
| |
- | panel.add(pressed);
| |
- | panel.add(armed);
| |
- |
| |
- | add(panel);
| |
- |
| |
- | setSize(350, 250);
| |
- | setLocationRelativeTo(null);
| |
- | setDefaultCloseOperation(EXIT_ON_CLOSE);
| |
- | setVisible(true);
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | new ButtonModel2();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | This example does the same thing as the previous one. The difference is that we don't use a change listener and
| |
- | we use a custom button model.
| |
- |
| |
- | <source lang="java">
| |
- | ButtonModel model = new DefaultButtonModel() {
| |
- | </source>
| |
- |
| |
- | We create a button model and overwrite the necessary methods.
| |
- |
| |
- | <source lang="java">
| |
- | public void setEnabled(boolean b) {
| |
- | if (b)
| |
- | enabled.setText("Pressed: true");
| |
- | else
| |
- | enabled.setText("Pressed: false");
| |
- |
| |
- | super.setEnabled(b);
| |
- | }
| |
- | </source>
| |
- |
| |
- | We overwrite the <b>setEnabled()</b> method and add some functionality there. We must not forget to call the parent method as well to procede with the processing.
| |
- |
| |
- | <source lang="java">
| |
- | ok.setModel(model);
| |
- | </source>
| |
- |
| |
- | We set the custom model for the button.
| |
- |
| |
- | == JList models ==
| |
- |
| |
- | Several components have two models. The <b>JList</b> component has the following models:
| |
- |
| |
- | <b>ListSelectionModel</b>. The ListModel handles data. And the
| |
- | ListSelectionModel works with the GUI. The following example shows both models.
| |
- |
| |
- | <source lang="java">
| |
- | import java.awt.BorderLayout;
| |
- | import java.awt.Dimension;
| |
- | import java.awt.event.ActionEvent;
| |
- | import java.awt.event.ActionListener;
| |
- | import java.awt.event.MouseAdapter;
| |
- | import java.awt.event.MouseEvent;
| |
- |
| |
- | import javax.swing.BorderFactory;
| |
- | import javax.swing.Box;
| |
- | import javax.swing.BoxLayout;
| |
- | import javax.swing.DefaultListModel;
| |
- | import javax.swing.JButton;
| |
- | import javax.swing.JFrame;
| |
- | import javax.swing.JList;
| |
- | import javax.swing.JOptionPane;
| |
- | import javax.swing.JPanel;
| |
- | import javax.swing.JScrollPane;
| |
- | import javax.swing.ListSelectionModel;
| |
- |
| |
- |
| |
- | public class List extends JFrame {
| |
- |
| |
- | private DefaultListModel model;
| |
- | private JList list;
| |
- |
| |
- | public List() {
| |
- |
| |
- | setTitle("JList models");
| |
- |
| |
- | model = new DefaultListModel();
| |
- | model.addElement("Amelie");
| |
- | model.addElement("Aguirre, der Zorn Gottes");
| |
- | model.addElement("Fargo");
| |
- | model.addElement("Exorcist");
| |
- | model.addElement("Schindler list");
| |
- |
| |
- | JPanel panel = new JPanel();
| |
- | panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
| |
- |
| |
- | JPanel leftPanel = new JPanel();
| |
- | JPanel rightPanel = new JPanel();
| |
- |
| |
- | leftPanel.setLayout(new BorderLayout());
| |
- | rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
| |
- |
| |
- | list = new JList(model);
| |
- | list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
| |
- | list.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
| |
- |
| |
- | list.addMouseListener(new MouseAdapter() {
| |
- |
| |
- | public void mouseClicked(MouseEvent e) {
| |
- | if(e.getClickCount() == 2){
| |
- | int index = list.locationToIndex(e.getPoint());
| |
- | Object item = model.getElementAt(index);
| |
- | String text = JOptionPane.showInputDialog("Rename item", item);
| |
- | String newitem = null;
| |
- | if (text != null)
| |
- | newitem = text.trim();
| |
- | else
| |
- | return;
| |
- |
| |
- | if (!newitem.isEmpty()) {
| |
- | model.remove(index);
| |
- | model.add(index, newitem);
| |
- | ListSelectionModel selmodel = list.getSelectionModel();
| |
- | selmodel.setLeadSelectionIndex(index);
| |
- | }
| |
- | }
| |
- | }
| |
- |
| |
- | });
| |
- |
| |
- | JScrollPane pane = new JScrollPane();
| |
- | pane.getViewport().add(list);
| |
- | leftPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
| |
- |
| |
- | leftPanel.add(pane);
| |
- |
| |
- | JButton removeall = new JButton("Remove All");
| |
- | JButton add = new JButton("Add");
| |
- | add.setMaximumSize(removeall.getMaximumSize());
| |
- | JButton rename = new JButton("Rename");
| |
- | rename.setMaximumSize(removeall.getMaximumSize());
| |
- | JButton delete = new JButton("Delete");
| |
- | delete.setMaximumSize(removeall.getMaximumSize());
| |
- |
| |
- | add.addActionListener(new ActionListener() {
| |
- | public void actionPerformed(ActionEvent e) {
| |
- | String text = JOptionPane.showInputDialog("Add a new item");
| |
- | String item = null;
| |
- |
| |
- | if (text != null)
| |
- | item = text.trim();
| |
- | else
| |
- | return;
| |
- |
| |
- | if (!item.isEmpty())
| |
- | model.addElement(item);
| |
- | }
| |
- | });
| |
- |
| |
- | delete.addActionListener(new ActionListener() {
| |
- | public void actionPerformed(ActionEvent event) {
| |
- | ListSelectionModel selmodel = list.getSelectionModel();
| |
- | int index = selmodel.getMinSelectionIndex();
| |
- | if (index >= 0)
| |
- | model.remove(index);
| |
- | }
| |
- |
| |
- | });
| |
- |
| |
- | rename.addActionListener(new ActionListener() {
| |
- |
| |
- | public void actionPerformed(ActionEvent e) {
| |
- | ListSelectionModel selmodel = list.getSelectionModel();
| |
- | int index = selmodel.getMinSelectionIndex();
| |
- | if (index == -1) return;
| |
- | Object item = model.getElementAt(index);
| |
- | String text = JOptionPane.showInputDialog("Rename item", item);
| |
- | String newitem = null;
| |
- |
| |
- | if (text != null) {
| |
- | newitem = text.trim();
| |
- | } else
| |
- | return;
| |
- |
| |
- | if (!newitem.isEmpty()) {
| |
- | model.remove(index);
| |
- | model.add(index, newitem);
| |
- | }
| |
- | }
| |
- | });
| |
- |
| |
- | removeall.addActionListener(new ActionListener() {
| |
- | public void actionPerformed(ActionEvent e) {
| |
- | model.clear();
| |
- | }
| |
- | });
| |
- |
| |
- | rightPanel.add(add);
| |
- | rightPanel.add(Box.createRigidArea(new Dimension(0,4)));
| |
- | rightPanel.add(rename);
| |
- | rightPanel.add(Box.createRigidArea(new Dimension(0,4)));
| |
- | rightPanel.add(delete);
| |
- | rightPanel.add(Box.createRigidArea(new Dimension(0,4)));
| |
- | rightPanel.add(removeall);
| |
- |
| |
- | rightPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 20));
| |
- |
| |
- | panel.add(leftPanel);
| |
- | panel.add(rightPanel);
| |
- |
| |
- | add(panel);
| |
- |
| |
- | setSize(350, 250);
| |
- | setLocationRelativeTo(null);
| |
- | setDefaultCloseOperation(EXIT_ON_CLOSE);
| |
- | setVisible(true);
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | new List();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | The example shows a list component and four buttons. The buttons control the data in the list component.
| |
- | The example is a bit larger, because we did some additional checks there. We do not allow to input empty spaces into the
| |
- | list component.
| |
- |
| |
- | <source lang="java">
| |
- | model = new DefaultListModel();
| |
- | model.addElement("Amelie");
| |
- | model.addElement("Aguirre, der Zorn Gottes");
| |
- | ...
| |
- |
| |
- | </source>
| |
- |
| |
- | We create a list model and add elements into it.
| |
- |
| |
- | <source lang="java">
| |
- | list = new JList(model);
| |
- | list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
| |
- | list.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
| |
- | </source>
| |
- |
| |
- | We create a list component. The parameter of the constructor is the model, we have created.
| |
- | We put the list into the single selection mode. We also put some space around the list.
| |
- |
| |
- | <source lang="java">
| |
- |
| |
- | if (text != null)
| |
- | item = text.trim();
| |
- | else
| |
- | return;
| |
- |
| |
- | if (!item.isEmpty())
| |
- | model.addElement(item);
| |
- | </source>
| |
- |
| |
- | We add only items that are not equal to null and are not empty. e.g. that contain at least one character other than white
| |
- | space. It makes no sense to add white spaces or null values into the list.
| |
- |
| |
- | <source lang="java">
| |
- | ListSelectionModel selmodel = list.getSelectionModel();
| |
- | int index = selmodel.getMinSelectionIndex();
| |
- | if (index >= 0)
| |
- | model.remove(index);
| |
- | </source>
| |
- |
| |
- | This is the code, that runs when we press the delete button. In order to delete an item from the list, it must
| |
- | be selected. So we must figure out the currently selected item. For this, we call the <b>getSelectionModel()</b> method This is a GUI work, so we use a
| |
- |
| |
- | <b>ListSelectionModel</b>. Removing an item is working with data. For that we use the list data model.
| |
- |
| |
- | So, in our example we used both list models. We called add(), remove() and clear() methods of the list data model to work with our data.
| |
- | And we used a list selection model in order to find out the selected item, which is a GUI job.
| |
- |
| |
- | [[image: java_swing_listmodels.png | center]]
| |
- |
| |
- | == A document model ==
| |
- |
| |
- | This is an excellent example of a separation of a data from the visual representation. In a <b>StyledDocument</b> for setting the style of the text data.
| |
- |
| |
- |
| |
- | <source lang="java">
| |
- | import java.awt.BorderLayout;
| |
- | import java.awt.Dimension;
| |
- | import java.awt.event.ActionEvent;
| |
- | import java.awt.event.ActionListener;
| |
- |
| |
- | import javax.swing.BorderFactory;
| |
- | import javax.swing.ImageIcon;
| |
- | import javax.swing.JButton;
| |
- | import javax.swing.JFrame;
| |
- | import javax.swing.JPanel;
| |
- | import javax.swing.JScrollPane;
| |
- | import javax.swing.JTextPane;
| |
- | import javax.swing.JToolBar;
| |
- | import javax.swing.text.Style;
| |
- | import javax.swing.text.StyleConstants;
| |
- | import javax.swing.text.StyledDocument;
| |
- |
| |
- |
| |
- | public class DocumentModel extends JFrame {
| |
- |
| |
- | private StyledDocument doc;
| |
- | private JTextPane textpane;
| |
- |
| |
- | public DocumentModel() {
| |
- |
| |
- | setTitle("Document Model");
| |
- |
| |
- | JToolBar toolbar = new JToolBar();
| |
- |
| |
- | ImageIcon bold = new ImageIcon("bold.png");
| |
- | ImageIcon italic = new ImageIcon("italic.png");
| |
- | ImageIcon strike = new ImageIcon("strike.png");
| |
- | ImageIcon underline = new ImageIcon("underline.png");
| |
- |
| |
- | JButton boldb = new JButton(bold);
| |
- | JButton italb = new JButton(italic);
| |
- | JButton strib = new JButton(strike);
| |
- | JButton undeb = new JButton(underline);
| |
- |
| |
- | toolbar.add(boldb);
| |
- | toolbar.add(italb);
| |
- | toolbar.add(strib);
| |
- | toolbar.add(undeb);
| |
- |
| |
- | add(toolbar, BorderLayout.NORTH);
| |
- |
| |
- | JPanel panel = new JPanel();
| |
- | panel.setLayout(new BorderLayout());
| |
- | panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
| |
- |
| |
- | JScrollPane pane = new JScrollPane();
| |
- | textpane = new JTextPane();
| |
- | textpane.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
| |
- |
| |
- | doc = textpane.getStyledDocument();
| |
- |
| |
- | Style style = textpane.addStyle("Bold", null);
| |
- | StyleConstants.setBold(style, true);
| |
- |
| |
- | style = textpane.addStyle("Italic", null);
| |
- | StyleConstants.setItalic(style, true);
| |
- |
| |
- | style = textpane.addStyle("Underline", null);
| |
- | StyleConstants.setUnderline(style, true);
| |
- |
| |
- | style = textpane.addStyle("Strike", null);
| |
- | StyleConstants.setStrikeThrough(style, true);
| |
- |
| |
- |
| |
- | boldb.addActionListener(new ActionListener() {
| |
- |
| |
- | public void actionPerformed(ActionEvent e) {
| |
- | doc.setCharacterAttributes(textpane.getSelectionStart(),
| |
- | textpane.getSelectionEnd() - textpane.getSelectionStart(),
| |
- | textpane.getStyle("Bold"), false);
| |
- | }
| |
- | });
| |
- |
| |
- | italb.addActionListener(new ActionListener() {
| |
- |
| |
- | public void actionPerformed(ActionEvent e) {
| |
- | doc.setCharacterAttributes(textpane.getSelectionStart(),
| |
- | textpane.getSelectionEnd() - textpane.getSelectionStart(),
| |
- | textpane.getStyle("Italic"), false);
| |
- | }
| |
- |
| |
- | });
| |
- |
| |
- | strib.addActionListener(new ActionListener() {
| |
- |
| |
- | public void actionPerformed(ActionEvent e) {
| |
- | doc.setCharacterAttributes(textpane.getSelectionStart(),
| |
- | textpane.getSelectionEnd() - textpane.getSelectionStart(),
| |
- | textpane.getStyle("Strike"), false);
| |
- | }
| |
- |
| |
- | });
| |
- |
| |
- | undeb.addActionListener(new ActionListener() {
| |
- |
| |
- | public void actionPerformed(ActionEvent e) {
| |
- | doc.setCharacterAttributes(textpane.getSelectionStart(),
| |
- | textpane.getSelectionEnd() - textpane.getSelectionStart(),
| |
- | textpane.getStyle("Underline"), false);
| |
- | }
| |
- | });
| |
- |
| |
- | pane.getViewport().add(textpane);
| |
- | panel.add(pane);
| |
- |
| |
- | add(panel);
| |
- |
| |
- | setSize(new Dimension(380, 320));
| |
- | setLocationRelativeTo(null);
| |
- | setDefaultCloseOperation(EXIT_ON_CLOSE);
| |
- | setVisible(true);
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | new DocumentModel();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | The example has a text pane and a toolbar. In the toolbar, we have four buttons, that change attributes of the text.
| |
- |
| |
- | <source lang="java">
| |
- | doc = textpane.getStyledDocument();
| |
- | </source>
| |
- |
| |
- | Here we get the styled document, which is a model for the text pane component.
| |
- |
| |
- | <source lang="java">
| |
- | Style style = textpane.addStyle("Bold", null);
| |
- | StyleConstants.setBold(style, true);
| |
- | </source>
| |
- |
| |
- |
| |
- | A style is a set of text attributes, such as color, size. Here we register a bold style for the text pane component. The registered styles can be retrieved at any time.
| |
- |
| |
- | <source lang="java">
| |
- | doc.setCharacterAttributes(textpane.getSelectionStart(),
| |
- | textpane.getSelectionEnd() - textpane.getSelectionStart(),
| |
- | textpane.getStyle("Bold"), false);
| |
- | </source>
| |
- |
| |
- | Here we change the attributes of the text. The parameters are the offset, length of the selection, the style and the boolean value replace. The offset is the beginning of the text, where we apply the bold text. We get the length value by substracting the selection end and selection start values. Boolean value false means, we are not replacing an old style with a new one, but we merge them. This means, if the text is underlined and we make it bold, the result is an underlined bold text.
| |
- |
| |
- | [[image: java_swing_documentmodel.png | center]]
| |
- |
| |
- | [[Категория:Java]]
| |