Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 

Swing Chapter 20. (Advanced topics) Constructing a Word Processor. Easy for reading, Click here!

Custom Search
Swing Chapter 20. (Advanced topics) Constructing a Word Processor. Easy for reading, Click here!

[ Return to Swing (Book) ]

Page: 7/9 



Previous Page Previous Page (6/9) - Next Page (8/9) Next Page
Subpages: 1. Word Processor: part I - Introducing RTF
2. Word Processor: part II - Managing fonts
3. Word Processor: part III - Colors and images
4. Word Processor: part IV - Working with styles
5. Word Processor: part V - Clipboard and undo/redo
6. Word Processor: part VI - Advanced font mangement
7. Word Processor: part VII - Paragraph formatting
8. Word Processor: part VIII - Find and replace
9. Word Processor: part IX - Spell checker [using JDBC and SQL]

20.7  Word Processor: part VII - Paragraph formatting

Control over paragraph formatting attributes (e.g. line spacing, text alignment, left and right margins, etc.) is just as necessary in word processor applications as font attribute control. Swing supports a number of paragraph settings discussed below which we discussed briefly in chapter 19. In this section we'll add a dialog specifically for editing these settings. The most interesting aspect of this dialog is a special component we've designed to allow a preview of formatted text. In this way the user can get a feeling for how a setting change, or group of changes, will affect the actual document.

Figure 20.8 RTF word processor displaying a custom paragraph attributes dialog.

<<file figure20-8.gif>>

The Code: WordProcessor.java

see \Chapter20\7

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.util.*;

import javax.swing.*;

import javax.swing.text.*;

import javax.swing.event.*;

import javax.swing.border.*;

import javax.swing.text.rtf.*;

import javax.swing.undo.*;

public class WordProcessor extends JFrame

{

  // Unchanged code from section 20.6

  protected FontDialog m_fontDialog;

  protected ParagraphDialog m_paragraphDialog;

  protected JMenuBar createMenuBar() {

    // Unchanged code from section 20.6

    m_fontDialog = new FontDialog(this, m_fontNames, m_fontSizes);

    m_paragraphDialog = new ParagraphDialog(this);

    // Unchanged code from section 20.6

    item = new JMenuItem("Paragraph...");

    item.setMnemonic('p');

    lst = new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        WordProcessor.this.repaint();

        AttributeSet a = m_doc.getCharacterElement(

          m_monitor.getCaretPosition()).getAttributes();

        m_paragraphDialog.setAttributes(a);

        Dimension d1 = m_paragraphDialog.getSize();

        Dimension d2 = WordProcessor.this.getSize();

        int x = Math.max((d2.width-d1.width)/2, 0);

        int y = Math.max((d2.height-d1.height)/2, 0);

        m_paragraphDialog.setBounds(x + WordProcessor.this.getX(),

          y + WordProcessor.this.getY(), d1.width, d1.height);

        m_paragraphDialog.show();

        if (m_paragraphDialog.getOption()==JOptionPane.OK_OPTION) {

          setAttributeSet(dlg.getAttributes(), true);

          showAttributes(m_monitor.getCaretPosition());

        }

      }

    };

    item.addActionListener(lst);

    mFormat.add(item);

    mFormat.addSeparator();

    // Unchanged code from section 20.6

    return menuBar;

  }

  // Unchanged code from section 20.6

  protected void setAttributeSet(AttributeSet attr) {

    setAttributeSet(attr, false);

  }

  protected void setAttributeSet(AttributeSet attr,

   boolean setParagraphAttributes)

  {

    if (m_skipUpdate)

      return;

    int xStart = m_monitor.getSelectionStart();

    int xFinish = m_monitor.getSelectionEnd();

    if (!m_monitor.hasFocus()) {

      xStart = m_xStart;

      xFinish = m_xFinish;

    }

    if (setParagraphAttributes)

      m_doc.setParagraphAttributes(xStart,

      xFinish - xStart, attr, false);

    else if (xStart != xFinish)

      m_doc.setCharacterAttributes(xStart,

        xFinish - xStart, attr, false);

    else {

      MutableAttributeSet inputAttributes =

        m_kit.getInputAttributes();

      inputAttributes.addAttributes(attr);

    }

  }

  // Unchanged code from section 20.6

}

// Unchanged code from section 20.6

class ParagraphDialog extends JDialog

{

  protected int m_option = JOptionPane.CLOSED_OPTION;

  protected MutableAttributeSet m_attributes;

  protected JTextField m_lineSpacing;

  protected JTextField m_spaceAbove;

  protected JTextField m_spaceBelow;

  protected JTextField m_firstIndent;

  protected JTextField m_leftIndent;

  protected JTextField m_rightIndent;

  protected SmallToggleButton m_btLeft;

  protected SmallToggleButton m_btCenter;

  protected SmallToggleButton m_btRight;

  protected SmallToggleButton m_btJustified;

  protected ParagraphPreview m_preview;

  public ParagraphDialog(JFrame parent) {

    super(parent, "Paragraph", true);

    getContentPane().setLayout(new BoxLayout(getContentPane(),

      BoxLayout.Y_AXIS));

    JPanel p = new JPanel(new GridLayout(1, 2, 5, 2));

    JPanel ps = new JPanel(new GridLayout(3, 2, 10, 2));

    ps.setBorder(new TitledBorder(new EtchedBorder(), "Space"));

    ps.add(new JLabel("Line spacing:"));

    m_lineSpacing = new JTextField();

    ps.add(m_lineSpacing);

    ps.add(new JLabel("Space above:"));

    m_spaceAbove = new JTextField();

    ps.add(m_spaceAbove);

    ps.add(new JLabel("Space below:"));

    m_spaceBelow = new JTextField();

    ps.add(m_spaceBelow);

    p.add(ps);

    JPanel pi = new JPanel(new GridLayout(3, 2, 10, 2));

    pi.setBorder(new TitledBorder(new EtchedBorder(), "Indent"));

    pi.add(new JLabel("First indent:"));

    m_firstIndent = new JTextField();

    pi.add(m_firstIndent);

    pi.add(new JLabel("Left indent:"));

    m_leftIndent = new JTextField();

    pi.add(m_leftIndent);

    pi.add(new JLabel("Right indent:"));

    m_rightIndent = new JTextField();

    pi.add(m_rightIndent);

    p.add(pi);

    getContentPane().add(p);

    getContentPane().add(Box.createVerticalStrut(5));

    p = new JPanel();

    p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));

    p.add(Box.createHorizontalStrut(10));

    p.add(new JLabel("Alignment:"));

    p.add(Box.createHorizontalStrut(20));

    ButtonGroup bg = new ButtonGroup();

    ImageIcon img = new ImageIcon("al_left.gif");

    m_btLeft = new SmallToggleButton(false, img, img, "Left");

    bg.add(m_btLeft);

    p.add(m_btLeft);

    img = new ImageIcon("al_center.gif");

    m_btCenter = new SmallToggleButton(false, img, img, "Center");

    bg.add(m_btCenter);

    p.add(m_btCenter);

    img = new ImageIcon("al_right.gif");

    m_btRight = new SmallToggleButton(false, img, img, "Right");

    bg.add(m_btRight);

    p.add(m_btRight);

    img = new ImageIcon("al_justify.gif");

    m_btJustified = new SmallToggleButton(false, img, img,

      "Justify");

    bg.add(m_btJustified);

    p.add(m_btJustified);

    getContentPane().add(p);

    p = new JPanel(new BorderLayout());

    p.setBorder(new TitledBorder(new EtchedBorder(), "Preview"));

    m_preview = new ParagraphPreview();

    p.add(m_preview, BorderLayout.CENTER);

    getContentPane().add(p);

    p = new JPanel(new FlowLayout());

    JPanel p1 = new JPanel(new GridLayout(1, 2, 10, 2));

    JButton btOK = new JButton("OK");

    ActionListener lst = new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        m_option = JOptionPane.OK_OPTION;

        setVisible(false);

      }

    };

    btOK.addActionListener(lst);

    p1.add(btOK);

    JButton btCancel = new JButton("Cancel");

    lst = new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        m_option = JOptionPane.CANCEL_OPTION;

        setVisible(false);

      }

    };

    btCancel.addActionListener(lst);

    p1.add(btCancel);

    p.add(p1);

    getContentPane().add(p);

    pack();

    setResizable(false);

    FocusListener flst = new FocusListener() {

      public void focusGained(FocusEvent e) {}

      public void focusLost(FocusEvent e) { updatePreview(); }

    };

    m_lineSpacing.addFocusListener(flst);

    m_spaceAbove.addFocusListener(flst);

    m_spaceBelow.addFocusListener(flst);

    m_firstIndent.addFocusListener(flst);

    m_leftIndent.addFocusListener(flst);

    m_rightIndent.addFocusListener(flst);

    lst = new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        updatePreview();

      }

    };

    m_btLeft.addActionListener(lst);

    m_btCenter.addActionListener(lst);

    m_btRight.addActionListener(lst);

    m_btJustified.addActionListener(lst);

  }

  public void setAttributes(AttributeSet a) {

    m_attributes = new SimpleAttributeSet(a);

    m_lineSpacing.setText(Float.toString(

      StyleConstants.getLineSpacing(a)));

    m_spaceAbove.setText(Float.toString(

      StyleConstants.getSpaceAbove(a)));

    m_spaceBelow.setText(Float.toString(

      StyleConstants.getSpaceBelow(a)));

    m_firstIndent.setText(Float.toString(

      StyleConstants.getFirstLineIndent(a)));

    m_leftIndent.setText(Float.toString(

      StyleConstants.getLeftIndent(a)));

    m_rightIndent.setText(Float.toString(

      StyleConstants.getRightIndent(a)));

    int alignment = StyleConstants.getAlignment(a);

    if (alignment == StyleConstants.ALIGN_LEFT)

      m_btLeft.setSelected(true);

    else if (alignment == StyleConstants.ALIGN_CENTER)

      m_btCenter.setSelected(true);

    else if (alignment == StyleConstants.ALIGN_RIGHT)

      m_btRight.setSelected(true);

    else if (alignment == StyleConstants.ALIGN_JUSTIFIED)

      m_btJustified.setSelected(true);

    updatePreview();

  }

  public AttributeSet getAttributes() {

    if (m_attributes == null)

      return null;

    float value;

    try {

      value = Float.parseFloat(m_lineSpacing.getText());

      StyleConstants.setLineSpacing(m_attributes, value);

    } catch (NumberFormatException ex) {}

    try {

      value = Float.parseFloat(m_spaceAbove.getText());

      StyleConstants.setSpaceAbove(m_attributes, value);

    } catch (NumberFormatException ex) {}

    try {

      value = Float.parseFloat(m_spaceBelow.getText());

      StyleConstants.setSpaceBelow(m_attributes, value);

    } catch (NumberFormatException ex) {}

    try {

      value = Float.parseFloat(m_firstIndent.getText());

      StyleConstants.setFirstLineIndent(m_attributes, value);

    } catch (NumberFormatException ex) {}

    try {

      value = Float.parseFloat(m_leftIndent.getText());

      StyleConstants.setLeftIndent(m_attributes, value);

    } catch (NumberFormatException ex) {}

    try {

      value = Float.parseFloat(m_rightIndent.getText());

      StyleConstants.setRightIndent(m_attributes, value);

    } catch (NumberFormatException ex) {}

    StyleConstants.setAlignment(m_attributes, getAlignment());

    return m_attributes;

  }

  public int getOption() {

    return m_option;

  }

  protected void updatePreview() {

    m_preview.repaint();

  }

  protected int getAlignment() {

    if (m_btLeft.isSelected())

      return StyleConstants.ALIGN_LEFT;

    if (m_btCenter.isSelected())

      return StyleConstants.ALIGN_CENTER;

    else if (m_btRight.isSelected())

      return StyleConstants.ALIGN_RIGHT;

    else

      return StyleConstants.ALIGN_JUSTIFIED;

  }

  class ParagraphPreview extends JPanel

  {

    protected Font m_fn = new Font("Monospace", Font.PLAIN, 6);

    protected String m_dummy = "abcdefghjklm";

    protected float  m_scaleX = 0.25f;

    protected float  m_scaleY = 0.25f;

    protected Random m_random = new Random();

    public ParagraphPreview() {

      setBackground(Color.white);

      setForeground(Color.black);

      setOpaque(true);

      setBorder(new LineBorder(Color.black));

      setPreferredSize(new Dimension(120, 56));

    }

    public void paintComponent(Graphics g) {

      super.paintComponent(g);

      float lineSpacing = 0;

      float spaceAbove  = 0;

      float spaceBelow  = 0;

      float firstIndent = 0;

      float leftIndent  = 0;

      float rightIndent = 0;

      try {

        lineSpacing = Float.parseFloat(m_lineSpacing.getText());

      } catch (NumberFormatException ex) {}

      try {

        spaceAbove = Float.parseFloat(m_spaceAbove.getText());

      } catch (NumberFormatException ex) {}

      try {

        spaceBelow = Float.parseFloat(m_spaceBelow.getText());

      } catch (NumberFormatException ex) {}

      try {

        firstIndent = Float.parseFloat(m_firstIndent.getText());

      } catch (NumberFormatException ex) {}

      try {

        leftIndent = Float.parseFloat(m_leftIndent.getText());

      } catch (NumberFormatException ex) {}

      try {

        rightIndent = Float.parseFloat(m_rightIndent.getText());

      } catch (NumberFormatException ex) {}

      m_random.setSeed(1959);    // Use same seed every time

      g.setFont(m_fn);

      FontMetrics fm = g.getFontMetrics();

      int h = fm.getAscent();

      int s  = Math.max((int)(lineSpacing*m_scaleY), 1);

      int s1 = Math.max((int)(spaceAbove*m_scaleY), 0) + s;

      int s2 = Math.max((int)(spaceBelow*m_scaleY), 0) + s;

      int y = 5+h;

      int xMarg = 20;

      int x0 = Math.max((int)(firstIndent*m_scaleX)+xMarg, 3);

      int x1 = Math.max((int)(leftIndent*m_scaleX)+xMarg, 3);

      int x2 = Math.max((int)(rightIndent*m_scaleX)+xMarg, 3);

      int xm0 = getWidth()-xMarg;

      int xm1 = getWidth()-x2;

      int n = (int)((getHeight()-(2*h+s1+s2-s+10))/(h+s));

      n = Math.max(n, 1);

      g.setColor(Color.lightGray);

      int x = xMarg;

      drawLine(g, x, y, xm0, xm0, fm, StyleConstants.ALIGN_LEFT);

      y += h+s1;

      g.setColor(Color.gray);

      int alignment = getAlignment();

      for (int k=0; k<n; k++) {

        x = (k==0 ? x0 : x1);

        int xLen = (k==n-1 ? xm1/2 : xm1);

        if (k==n-1 && alignment==StyleConstants.ALIGN_JUSTIFIED)

          alignment = StyleConstants.ALIGN_LEFT;

        drawLine(g, x, y, xm1, xLen, fm, alignment);

        y += h+s;

      }

      y += s2-s;

      x = xMarg;

      g.setColor(Color.lightGray);

      drawLine(g, x, y, xm0, xm0, fm, StyleConstants.ALIGN_LEFT);

    }

    protected void drawLine(Graphics g, int x, int y, int xMax,

     int xLen, FontMetrics fm, int alignment)

    {

      if (y > getHeight()-3)

        return;

      StringBuffer s = new StringBuffer();

      String str1;

      int xx = x;

      while (true) {

        int m = m_random.nextInt(10)+1;

        str1 = m_dummy.substring(0, m)+" ";

        int len = fm.stringWidth(str1);

        if (xx+len >= xLen)

          break;

        xx += len;

        s.append(str1);

      }

      String str = s.toString();

      switch (alignment) {

        case StyleConstants.ALIGN_LEFT:

          g.drawString(str, x, y);

          break;

        case StyleConstants.ALIGN_CENTER:

          xx = (xMax+x-fm.stringWidth(str))/2;

          g.drawString(str, xx, y);

          break;

        case StyleConstants.ALIGN_RIGHT:

          xx = xMax-fm.stringWidth(str);

          g.drawString(str, xx, y);

          break;

        case StyleConstants.ALIGN_JUSTIFIED:

          while (x+fm.stringWidth(str) < xMax)

            str += "a";

          g.drawString(str, x, y);

          break;

      }

    }

  }

}

Understanding the Code

Class WordProcessor

One new instance variable has been added:

ParagraphDialog m_paragraphDialog: custom dialog used to manage paragraph attributes.

A new menu item titled "Paragraph..." is now added to the "Format" menu. A corresponding ActionListener acts similarly to the listener of "Font..." menu. It repaints the entire application, retrieves a set of attributes corresponding to the character element at the current caret position, and passes this set to m_paragraphDialog. The dialog is then centered with respect to its parent (WordProcessor in our case) and shows itself. When the "OK" or "Cancel" button is pressed, the result returned by the getOption() method is normally checked. If the returned value is equal to JOptionPane.OK_OPTION (i.e. "OK" was pressed) we retrieve the selected attributes with ParagraphDialog's getAttributes() method and assign them to the selected text with our setAttributeSet() method. Otherwise we make no changes.

An additional parameter, a boolean, is added to our setAttributeSet() method. This is used to distinguish between setting character attributes and setting paragraph attributes. A value of true indicates that the given attribute set corresponds to paragraph attributes. A value of false indicates character attributes. To preserve the existing code without requiring extensive modification, we keep the old setAttributeSet() method with one parameter, and redirect it to the new method by having it call setAttributeSet(attr, false).

Class ParagraphDialog

This class extends JDialog and acts as a paragraph attributes editor for our word processor application. Several instance variables are declared:

int m_option: indicates how the dialog is closed: by pressing the "OK" button, by pressing the "Cancel" button, or by closing the dialog window directly from the title bar. The constants defined in JOptionPane are reused for this variable.

MutableAttributeSet m_attributes: a collection of paragraph attributes used to preserve the user's selection.

JTextField m_lineSpacing: used to specify paragraph line spacing.

JTextField m_spaceAbove: used to specify above line spacing.

JTextField m_spaceBelow: used to specify below line spacing.

JTextField m_firstIndent: used to specify left indent of the first paragraph line.

JTextField m_leftIndent: used to specify left indent of all other paragraph lines (other than the first).

JTextField m_rightIndent: used to specify right indent of all paragraph lines.

SmallToggleButton m_btLeft: used to toggle left text alignment.

SmallToggleButton m_btCenter: used to toggle center text alignment.

SmallToggleButton m_btRight: used to toggle right text alignment.

SmallToggleButton m_btJustified: used to toggle justified text alignment.

ParagraphPreview m_preview: custom component for previewing paragraph attribute effects .

The ParagraphDialog constructor first creates a super-class modal dialog titled "Paragraph." This dialog uses a y-oriented BoxLayout to place component groups from top to bottom. Six text fields listed above are placed in two side-by-side panels titled "Space" and "Indent." These controls allow the user to specify spacing attributes. Below these fields is a group of SmallToggleButtons (introduced in chapter 12) used to control text alignment: left, center, right, or justified.

An instance of our custom ParagraphPreview component, m_preview, is used to preview the selected paragraph attributes before applying them to the selected document text. We will discuss how this component works below.

Two buttons labeled "OK" and "Cancel" are placed at the bottom of the dialog and act identically to those at the bottom of our font dialog (see previous exampple). The six text boxes mentioned above receive an identical FocusListener which invokes our updatePreview() method (see below) when a text field loses focus. Similarly, the four toggle buttons receive an identical ActionListener which does the same thing. This provides a dynamic preview of the selected paragraph attributes whenever any attribute is changed.

The setAttributes() method takes an AttributeSet instance as parameter. It copies this attribute set into a SimpleAttributeSet stored as our m_attributes instance variable. Appropriate paragraph attributes are extracted using StyleConstants methods, and used to assign values to the dialog's controls. Finally the preview component is updated according to these new settings by calling our updatePreview() method. Note that the setAttributes() method is public and is used for data exchange between this dialog and it's owner (in our case WordProcessor).

The method getAttributes() plays an opposite role with respect to setAttributes(). It retrieves data from the dialog's controls, packs them into an AttributeSet instance using StyleConstants methods, and return this set to the caller.

Note: All spacing variables are of type float, even though they are actually measured in discrete screen pixels.

The getOption() method returns a code indicating how the dialog was closed by the user. This value should be checked prior to retrieving data from the dialog to determine whether or not the user canceled (JOptionPane.CANCEL_OPTION) or ok'd (JOptionPane.OK_OPTION) the changes.

The updatePreview() method is called to update the paragraph preview component whenever a paragraph attribute is changed. It simply forces our m_preview component to repaint itself.

The getAlignment() method checks for the selected toggle button and returns the corresponding alignment attribute.

Class ParagraphDialog.ParagraphPreview

This inner class represents our custom component used to display an imitation paragraph used to preview a set of paragraph attributes. The actual rendering consists of three parts:

1.  A light gray text line representing the end of a preceding paragraph. The indent and spacing of this line is not affected by the current paragraph attribute settings.

2.  Several gray text lines representing a paragraph being modified. Indentations and line spacing depend on the current paragraph attribute settings. The number of these lines is calculated so as to fill the component's height naturally, and depends on the current line spacing attribute settings.

3.  A light gray text line representing the beginning of a following paragraph. The space between this line and the last paragraph line depends on the current above line spacing attribute. The indentation of this line is not affected by the current paragraph attributes.

Several instance variables are declared in this inner class:

Font m_fn: the font used for preview paragraph rendering. This font is intentionally made small and barely recognizable, because the displayed text itself does not have any meaning; only the paragraph formatting does.

String m_dummy: a dummy string used in random generation of a paragraph.

float m_scaleX: the scaling factor used to re-calculate sizes in the vertical direction.

float m_scaleY: the scaling factor used to re-calculate sizes in the horizontal direction.

Random m_random: random number generator used in piecing together a paragraph of characters.

Reminder: java.util.Random provides random number generation capabilities, including seed selection, generation of integers in a given range, etc. In the simplest cases we can use the Math.random() static method instead.

The ParagraphPreview constructor initializes the colors, border, and preferred size for this component.

The most interesting aspect of the preview component's work is done in the paintComponent() method. First, this method retrieves the paragraph attributes specified by the user. Then we set a hard-coded seed value for our random number generator, m_random, which we use to generate a paragraph of gibberish. The following local variables are used to control the placement of this paragraph's lines:

int h: the height of the text string determined by the font selected for preview.

int s: spacing between lines in screen pixels.

int s1: actual spacing between the previous paragraph and the first line of this paragraph.

int s2: actual spacing between the following paragraph and the last line of this paragraph.

int y: vertical position of the text being drawn (to be updated during the rendering process).

int xMarg: left and right fixed margins.

int x0: actual left indent for the first line of this paragraph.

int x1: actual left indent for the second and remaining following lines of this paragraph.

int x2: actual right indent for the lines of this paragraph.

int xm0: maximum x-coordinate for the text lines without regard to the specified right indent.

int xm1: maximum x-coordinate for the text lines with regard to the specified right indent.

int n: number of paragraph lines which can fit vertically within this component, taking into account the specified line spacing and both the preceding and following paragraph lines.

Once all these variables are calculated, the rendering can be performed relatively easily. The drawLine() method is used to draw a single line of text. First we draw a line denoting the preceding paragraph, then we draw each line of the current paragraph, and finally, a line denoting the following paragraph. Note that the last line of the current paragraph is intentionally half the length of a normal line to produce a more realistic impression of the text. Also, when justified alignment is specified, it is suppressed for the last line of text, since the last line should not be stretched.

The drawLine() method takes seven parameters:

Graphics g: used for all rendering.

int x, int y: coordinates of the beginning of a text line.

int xMax: maximum x-coordinate a line can occupy.

int xLen: line length plus left margin size.

FontMetrics fm: retrieved from the current Graphics instance.

int alignment: current text alignment.

First this method prepares a line to be drawn by concatenating random pieces of the m_dummy string until the resulting length, plus the left margin size, is greater than or equal to the xLen parameter. (Note that a StringBuffer instance is used here to improve performance.) Then we draw this line depending on the selected alignment. For left alignment we simply start drawing at the left margin. For center and right alignments we calculate the start position by working with the maximum x-coordinate, and the width of that line. For justified alignment we should recalculate space between words so the resulting line will occupy all available width (however, in our case, since the preview text is totally meaningless, we just add some more text at the right end).

Running the Code

Open an existing RTF file, select some text and bring up the "Paragraph" dialog. Verify that the initial values of all components correspond to the paragraph attributes at the current caret position. Specify new paragraph attributes and note how the preview component is updated dynamically. Press the "OK" button to apply the specified attributes to the selected paragraphs of document text.

Bug Alert! Justified text alignment has not been implemented as of Java 2 FCS.



[ Return to Swing (Book) ]


Top 10 read Java Articles
 Get free "1000 Java Tips eBook"

 Java Calendar and Date: good to know facts and code examples

 Array vs ArrayList vs LinkedList vs Vector: an excellent overview and examples

 How can I convert any Java Object into byte array? And byte array to file object

 The Java Lesson 1: What is Java?

 How do I compare two dates and times, date between dates, time between times and

 Maven vs Ant or Ant vs Maven?

 How to open, read, write, close file(s) in Java? Examples on move, rename and de

 Java Array

 Java: JLabel font and color


[ More in News Section ]
Java Lessons

The Java Lesson 1:
What is Java?
The Java Lesson 2:
Anatomy of a simple Java program
The Java Lesson 3:
Identifiers and primitive data types
The Java Lesson 4:
Variables, constants, and literals
The Java Lesson 5:
Arithmetic operations, conversions, and casts
The Java Lesson 6:
Boolean expressions and operations
The Java Lesson 7:
Bitwise operations
The Java Lesson 8:
Flow control with if and else
The Java Lesson 9:
switch statements
The Java Lesson 10:
for, while, and do-while statements
The Java Lesson 11:
Using break and continue
The Java Lesson 12:
Class methods and how they are called
The Java Lesson 13:
Using the Math class
The Java Lesson 14:
Creating and calling custom class methods
The Java Lesson 15:
Overloading class methods
The Java Lesson 16:
An introduction to objects and object references
The Java Lesson 17:
The String class
The Java Lesson 18:
The StringBuffer class
The Java Lesson 19:
Initializing and processing arrays of primitives
The Java Lesson 20:
Initializing and processing arrays of objects
The Java Lesson 23:
Inheritance and overriding inherited methods
The Java Lesson 24:
abstract classes and polymorphism
The Java Lesson 25:
Interfaces, instanceof, and object conversion and casting
The Java Lesson 26:
Introduction to graphical programming and the java.awt packa
The Java Lesson 27:
The Component class
The Java Lesson 28:
Containers and simple layout managers
The Java Lesson 29:
The Color and Font classes
The Java Lesson 30:
Drawing geometric shapes
The Java Lesson 31:
Choice, List, and Checkbox controls
The Java Lesson 32:
Using the Scrollbar graphical control
The Java Lesson 33:
Menus and submenus
The Java Lesson 34:
An introduction to applets and the Applet class
The Java Lesson 35:
Essential HTML to launch an applet and pass it parameters
The Java Lesson 36:
Mouse event processing
Java Lesson 37:
Menus and submenus
Java Lesson 38:
The WindowListener interface and the WindowAdapter class
Java Lesson 39:
An introduction to GridBagLayout
Java Lesson 40:
An introduction to the Java Collections API
Java Lesson 41:
Exception handling with try, catch, and finally blocks
Java Lesson 42:
Claiming and throwing exceptions
Java Lesson 43:
Multithreading, the Thread class, and the Runnable interface
Java Lesson 44:
An introduction to I/O and the File and FileDialog classes
Java Lesson 45:
Low-level and high-level stream classes
Java Lesson 46:
Using the RandomAccessFile class
Java Lessons by
Joh Huhtala: Update

Latest articles
 Java Profiler JProbe to Resolve Performance Problems Faster

 SSL with GlassFish v2, page 5

 SSL with GlassFish v2, page 4

 SSL with GlassFish v2, page 3

 SSL with GlassFish v2, page 2

 The Java Lesson 2: Anatomy of a simple Java program, page 2

 New site about Java for robots and robotics: both software and hardware.

 Exceptions -III: What's an exception and why do I care?

 Exceptions -II: What's an exception and why do I care?

 Exceptions: What's an exception and why do I care?

 Double your Java code quality in 10 minutes, here is receipt

 Murach's Java Servlets and JSP

 How to get ascii code from a char in Java?

 Can we just try without catch? Yes!

 Make Tomcat page load faster

 Make your Tomcat More secure - limit network address for certain IP addresses

 New Java book online starts now here...

 Implementing RESTful Web Services in Java

 Firefox trimming from 1 GB to 40 Mb with many tabs opened

 SSL with GlassFish v2

 My request to replublish Tech Tips

 Search JavaFAQ.nu site here

 New Advanced Installer for Java 6.0 brings XML updates and imports 3rd party MSI

 EJB programming restrictions

 Maven vs Ant or Ant vs Maven?

 Why Java does not use default value which it should?

 How to unsign signed bytes in Java - your guide is here

 The Java Lesson 3: Identifiers and primitive data types. Page 2

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 4

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 3


[ More in News Section ]


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy