Java Tutorial/Swing Event/ComponentListener

Материал из Java эксперт
Перейти к: навигация, поиск

A ComponentAdapter.

import java.awt.event.ruponentAdapter;
import java.awt.event.ruponentEvent;
import javax.swing.JFrame;
class MoveAdapter extends ComponentAdapter {
  public void componentMoved(ComponentEvent e) {
    int x = e.getComponent().getX();
    int y = e.getComponent().getY();
    System.out.println("x: " + x);
    System.out.println("y: " + y);
  }
}
public class Adapter {
  public static void main(String[] args) {
    JFrame f = new JFrame();
    f.addComponentListener(new MoveAdapter());
    f.setSize(310, 200);
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
  }
}





A position of a window on the screen.

import java.awt.event.ruponentEvent;
import java.awt.event.ruponentListener;
import javax.swing.JFrame;
public class MovingWindow extends JFrame implements ComponentListener {
  public MovingWindow() {
    addComponentListener(this);
    setSize(310, 200);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
  }
  public void componentResized(ComponentEvent e) {
  }
  public void componentMoved(ComponentEvent e) {
    int x = e.getComponent().getX();
    int y = e.getComponent().getY();
    System.out.println("x: " + x);
    System.out.println("y: " + y);
  }
  public void componentShown(ComponentEvent e) {
  }
  public void componentHidden(ComponentEvent e) {
  }
  public static void main(String[] args) {
    new MovingWindow();
  }
}





ComponentListener and ComponentEvent

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * ComponentEventDemo.java requires no other files.
 */
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ruponentEvent;
import java.awt.event.ruponentListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class ComponentEventDemo extends JPanel implements ComponentListener,
    ItemListener {
  static JFrame frame;
  JTextArea display;
  JLabel label;
  String newline = "\n";
  public ComponentEventDemo() {
    super(new BorderLayout());
    display = new JTextArea();
    display.setEditable(false);
    JScrollPane scrollPane = new JScrollPane(display);
    scrollPane.setPreferredSize(new Dimension(350, 200));
    JPanel panel = new JPanel(new BorderLayout());
    label = new JLabel("This is a label", JLabel.CENTER);
    label.addComponentListener(this);
    panel.add(label, BorderLayout.CENTER);
    JCheckBox checkbox = new JCheckBox("Label visible", true);
    checkbox.addItemListener(this);
    checkbox.addComponentListener(this);
    panel.add(checkbox, BorderLayout.PAGE_END);
    panel.addComponentListener(this);
    add(scrollPane, BorderLayout.CENTER);
    add(panel, BorderLayout.PAGE_END);
    frame.addComponentListener(this);
  }
  public void itemStateChanged(ItemEvent e) {
    if (e.getStateChange() == ItemEvent.SELECTED) {
      label.setVisible(true);
      // Need to revalidate and repaint, or else the label
      // will probably be drawn in the wrong place.
      label.revalidate();
      label.repaint();
    } else {
      label.setVisible(false);
    }
  }
  protected void displayMessage(String message) {
    // If the text area is not yet realized, and
    // we tell it to draw text, it could cause
    // a text/AWT tree deadlock. Our solution is
    // to ensure that the text area is realized
    // before attempting to draw text.
    // if (display.isShowing()) {
    display.append(message + newline);
    display.setCaretPosition(display.getDocument().getLength());
    // }
  }
  public void componentHidden(ComponentEvent e) {
    displayMessage(e.getComponent().getClass().getName() + " --- Hidden");
  }
  public void componentMoved(ComponentEvent e) {
    displayMessage(e.getComponent().getClass().getName() + " --- Moved");
  }
  public void componentResized(ComponentEvent e) {
    displayMessage(e.getComponent().getClass().getName() + " --- Resized ");
  }
  public void componentShown(ComponentEvent e) {
    displayMessage(e.getComponent().getClass().getName() + " --- Shown");
  }
  /**
   * Create the GUI and show it. For thread safety, this method should be
   * invoked from the event-dispatching thread.
   */
  private static void createAndShowGUI() {
    // Create and set up the window.
    frame = new JFrame("ComponentEventDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // Create and set up the content pane.
    JComponent newContentPane = new ComponentEventDemo();
    newContentPane.setOpaque(true); // content panes must be opaque
    frame.setContentPane(newContentPane);
    // Display the window.
    frame.pack();
    frame.setVisible(true);
  }
  public static void main(String[] args) {
    // Schedule a job for the event-dispatching thread:
    // creating and showing this application"s GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
}





extends ComponentAdapter

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ruponentAdapter;
import java.awt.event.ruponentEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
public class RowAdder extends JFrame {
  SimpleModel tableData = new SimpleModel();
  JTable table = new JTable(tableData);
 
  public static void main(String[] args) {
    RowAdder ra = new RowAdder();
    ra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ra.setSize(400, 300);
    ra.setVisible(true);
  }
  public RowAdder() {
    setLayout(new BorderLayout());
    table.addComponentListener(new TableScroller());
    add(new JScrollPane(table), BorderLayout.CENTER);
  }
  class TableScroller extends ComponentAdapter {
    public void componentResized(ComponentEvent event) {
      int lastRow = tableData.getRowCount() - 1;
      int cellTop = table.getCellRect(lastRow, 0, true).y;
      JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(
          JScrollPane.class, table);
      JViewport jvp = jsp.getViewport();
      int portHeight = jvp.getSize().height;
      int position = cellTop
          - (portHeight - table.getRowHeight() - table.getRowMargin());
      if (position >= 0) {
        jvp.setViewPosition(new Point(0, position));
      }
    }
  }
}
class SimpleModel extends AbstractTableModel {
  public void addText(String text) {
    fireTableDataChanged();
  }
  public int getRowCount() {
    return 100;
  }
  public int getColumnCount() {
    return 3;
  }
  public Object getValueAt(int row, int column) {
    return row+" "+column;
  }
}





How to Write a Component Listener

One or more component events are fired after the component is hidden, made visible, moved, or resized.



import java.awt.ruponent;
import java.awt.event.ruponentEvent;
import java.awt.event.ruponentListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
public class UsingComponentListener {
  public static void main(String[] a) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JCheckBox checkbox = new JCheckBox("Label visible", true);
    checkbox.addComponentListener(new ComponentListener() {
      public void componentHidden(ComponentEvent e) {
        System.out.println("componentHidden event from " + e.getComponent().getClass().getName());
      }
      public void componentMoved(ComponentEvent e) {
        Component c = e.getComponent();
        System.out.println("componentMoved event from " + c.getClass().getName()
            + "; new location: " + c.getLocation().x + ", " + c.getLocation().y);
      }
      public void componentResized(ComponentEvent e) {
        Component c = e.getComponent();
        System.out.println("componentResized event from " + c.getClass().getName() + "; new size: "
            + c.getSize().width + ", " + c.getSize().height);
      }
      public void componentShown(ComponentEvent e) {
        System.out.println("componentShown event from " + e.getComponent().getClass().getName());
      }
    });
    frame.add(checkbox, "North");
    frame.setSize(300, 200);
    frame.setVisible(true);
  }
}





Installs/resets a ComponentListener to resize the given window to minWidth/Height if needed

/*
 * $Id: WindowUtils.java,v 1.16 2009/05/25 16:37:52 kschaefe Exp $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
import java.awt.Window;
import java.awt.event.ruponentAdapter;
import java.awt.event.ruponentListener;
import javax.swing.SwingUtilities;
public class Utils {
  /**
   * Installs/resets a ComponentListener to resize the
   * given window to minWidth/Height if needed.
   *
   * @param window
   * @param minWidth
   * @param minHeight
   */
  public static void setMinimumSizeManager(Window window, int minWidth,
                                           int minHeight) {
      ComponentListener[] listeners = window.getComponentListeners();
      ComponentListener listener = null;
      for (ComponentListener l : listeners) {
          if (l instanceof MinSizeComponentListener) {
              listener = l;
              break;
          }
      }
      if (listener == null) {
          window.addComponentListener(new MinSizeComponentListener(
                  window, minWidth, minHeight));
      } else {
          ((MinSizeComponentListener) listener).resetSizes(minWidth,
                                                           minHeight);
      }
  }
  /**
   * Resets window size to minSize if needed.
   *
   * @author Patrick Wright
   */
  public static class MinSizeComponentListener extends ComponentAdapter {
      private Window window;
      private int minHeight;
      private int minWidth;
      MinSizeComponentListener(Window frame, int minWidth, int minHeight) {
          this.window = frame;
          resetSizes(minWidth, minHeight);
      }
      public void resetSizes(int minWidth, int minHeight) {
          this.minWidth = minWidth;
          this.minHeight = minHeight;
          adjustIfNeeded(window);
      }
      @Override
      public void componentResized(java.awt.event.ruponentEvent evt) {
          adjustIfNeeded((Window) evt.getComponent());
      }
      private void adjustIfNeeded(final Window window) {
          boolean doSize = false;
          int newWidth = window.getWidth();
          int newHeight = window.getHeight();
          if (newWidth < minWidth) {
              newWidth = minWidth;
              doSize = true;
          }
          if (newHeight < minHeight) {
              newHeight = minHeight;
              doSize = true;
          }
          if (doSize) {
              final int w = newWidth;
              final int h = newHeight;
              SwingUtilities.invokeLater(new Runnable() {
                  public void run() {
                      window.setSize(w, h);
                  }
              });
          }
      }
  }
}