Как сделать так, чтобы полоса прокрутки панели прокрутки двигалась автоматически с помощью курсора при нажатии кнопки TAB на клавиатуре? - PullRequest
2 голосов
/ 29 августа 2011

У меня следующий код. После выполнения следующего кода он показывает JFrame, связывающийся с JInternalFrame, который имеет JScrollPane. Этот JScrollPane имеет JPanel, имеет много элементов управления вводом. Так как размер JPanel больше из-за многих элементов управления вводом, чем размер JInternalFrame, поэтому я его прокручиваю.

import java.awt.Dimension;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class InterfaceDesign {

    public static void main(String args[]) {
        InterfaceDesign id = new InterfaceDesign();
        id.getPnlProjectDetail("My Project");
    }

    public void getPnlProjectDetail(String strProjectName) {
        JPanel pnlPjDetail = new JPanel();
        JScrollPane scrPjDetail;
        pnlPjDetail.setLayout(null);
        pnlPjDetail.setBounds(0, 0, 400, 400);
        JFrame frmtest = new JFrame();
        JInternalFrame interFrame = new JInternalFrame();
        interFrame.setBounds(0, 0, 280, 180);

        frmtest.setBounds(1, 1, 300, 200);
        pnlPjDetail.setPreferredSize(new Dimension(400, 400));

        JLabel lblFirstName = new JLabel("First Name");
        JLabel lblLastName = new JLabel("Last Name");
        JLabel lblAddress = new JLabel("Address");
        JLabel lblCity = new JLabel("City");
        JLabel lblZipCode = new JLabel("Zip Code");
        JLabel lblPhone = new JLabel("Phone");
        JLabel lblEmailID = new JLabel("Emain Id");

        JTextField tfFirstName = new JTextField();
        JTextField tfLastName = new JTextField();
        JTextField tfAddress = new JTextField();
        JTextField tfCity = new JTextField();
        JTextField tfZipCode = new JTextField();
        JTextField tfPhone = new JTextField();
        JTextField tfEmailID = new JTextField();

        lblFirstName.setBounds(25, 55, 85, 20);
        tfFirstName.setBounds(25, 85, 85, 20);
        pnlPjDetail.add(lblFirstName);
        pnlPjDetail.add(tfFirstName);

        lblLastName.setBounds(25, 115, 85, 20);
        tfLastName.setBounds(25, 145, 85, 20);
        pnlPjDetail.add(lblLastName);
        pnlPjDetail.add(tfLastName);

        lblAddress.setBounds(25, 175, 85, 20);
        tfAddress.setBounds(25, 205, 85, 20);
        pnlPjDetail.add(lblAddress);
        pnlPjDetail.add(tfAddress);

        lblCity.setBounds(25, 235, 85, 20);
        tfCity.setBounds(25, 265, 85, 20);
        pnlPjDetail.add(lblCity);
        pnlPjDetail.add(tfCity);

        lblZipCode.setBounds(25, 295, 85, 20);
        tfZipCode.setBounds(25, 325, 85, 20);
        pnlPjDetail.add(lblZipCode);
        pnlPjDetail.add(tfZipCode);

        lblPhone.setBounds(25, 355, 85, 20);
        tfPhone.setBounds(25, 385, 85, 20);
        pnlPjDetail.add(lblPhone);
        pnlPjDetail.add(tfPhone);

        lblEmailID.setBounds(25, 415, 85, 20);
        tfEmailID.setBounds(25, 445, 85, 20);
        pnlPjDetail.add(lblEmailID);
        pnlPjDetail.add(tfEmailID);

        scrPjDetail = new JScrollPane(pnlPjDetail);

        scrPjDetail.setAutoscrolls(true);

        //frmtest.setContentPane(scrProjectDetail);
        interFrame.setContentPane(scrPjDetail);
        JDesktopPane dpane = new JDesktopPane();
        interFrame.setVisible(true);
        dpane.add(interFrame);

        //frmtest.getLayeredPane().add(interFrame);
        frmtest.setContentPane(dpane);
        //frmtest.add(scrProjectDetail);
        frmtest.setVisible(true);
        frmtest.setResizable(false);
        frmtest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //return pnlPjDetail;
    }
}

Мне нужно ваше руководство в решении следующих проблем / сомнений

  1. Когда мы нажимаем кнопку TAB на клавиатуре, курсор перемещается из одного текстового поля в другое, но полоса прокрутки (здесь вертикальная полоса прокрутки) не перемещается автоматически вместе с курсором, когда курсор перемещается к нижним полям ввода. Как сделать перемещение полосы прокрутки сам с курсором, как он движется вниз или вверх?
  2. Поскольку это демонстрационный код, возможно ли добавить две JscrollPane в JInterNalFrame бок о бок?
  3. Необходимо ли пользователю JDesktopPane добавлять JInternalFrame в JFrame? т.е. это правда, что мы не можем добавить JInternalFrame следующим образом <JFrame>.getContentPane.add(<JInternalFrame>);

Ответы [ 4 ]

6 голосов
/ 29 августа 2011

Простая задача, удивительно необычные решения - лично я оцениваю каждое решение кода приложения, которое должно опираться на фокус, как причудливое ;-)

Невозможно придумать что-либо, не зависящее от фокуса: только чуть более удобное в обслуживании, не требуя focusListener для каждого компонента в форме. Вместо этого зарегистрируйте PropertyChangeListener в KeyboardFocusManager и выполните прокрутку, когда получите уведомление об изменении в свойстве constantFocusOwner

public static class FocusDrivenScroller implements PropertyChangeListener {

    private JComponent parent;

    public FocusDrivenScroller(JComponent parent) {
        this.parent = parent;
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        Component focused = (Component) evt.getNewValue();
        if (focused == null || !SwingUtilities.isDescendingFrom(focused, parent)) return;
        parent.scrollRectToVisible(focused.getBounds());
    }

}

Для использования в коде приложения создайте экземпляр формы, которая находится внутри JScrollPane

public void buildAndShowDetailsFrame(String strProjectName) {
    // the container to scroll such that a focused child
    // is visible when gaining focus
    JPanel detailsForm = new JPanel();
    KeyboardFocusManager.getCurrentKeyboardFocusManager()
        .addPropertyChangeListener("permanentFocusOwner", 
                new FocusDrivenScroller(detailsForm));

    // choose and use an appropriate LayoutManager
    // note: this is only an example!
    // real-world requirements most probably need a stronger one
    detailsForm.setLayout(new BoxLayout(detailsForm, BoxLayout.PAGE_AXIS));
    // quick fill with stuff 
    String[] labels = {"First Name", "Last Name", 
            "Address", "City", "Zip Code", "Phone", "Emain Id"};
    for (String string : labels) {
        detailsForm.add(new JLabel(string));
        detailsForm.add(new JTextField());
    }
    JFrame frame = new JFrame();
    frame.add(new JScrollPane(detailsForm));
    frame.pack();
    // force scrollbar to appear
    frame.setSize(frame.getWidth(), frame.getHeight()/2);
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

кроме первых строк этого метода, это всего лишь сокращенная версия кода OP (чтобы заманить его / ее в использование соответствующего LayoutManager :-)

3 голосов
/ 30 августа 2011

Прокрутка формы - необычная реализация предложения Клеопартры.

0 голосов
/ 29 августа 2011

попробуйте это:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class InterfaceDesign {

    private SrcollListener l = new SrcollListener();

    public static void main( String args[] ) {
        InterfaceDesign id = new InterfaceDesign();
        id.getPnlProjectDetail( "My Project" );
    }

    public void getPnlProjectDetail( String strProjectName ) {
        JPanel pnlPjDetail = new JPanel();
        JPanel pnlPjDetail2 = new JPanel();
        JScrollPane scrPjDetail;
        JScrollPane scrPjDetail2;
        pnlPjDetail.setLayout( null );
        pnlPjDetail.setBounds( 0, 0, 200, 250 );
        pnlPjDetail2.setLayout( null );
        pnlPjDetail2.setBounds( 0, 0, 200, 300 );
        JFrame frmtest = new JFrame();
        JInternalFrame interFrame = new JInternalFrame();
        interFrame.setBounds( 0, 0, 280, 180 );

        frmtest.setBounds( 1, 1, 600, 200 );
        pnlPjDetail.setPreferredSize( new Dimension( 200, 250 ) );
        pnlPjDetail2.setPreferredSize( new Dimension( 200, 300 ) );

        JLabel lblFirstName = new JLabel( "First Name" );
        JLabel lblLastName = new JLabel( "Last Name" );
        JLabel lblAddress = new JLabel( "Address" );
        JLabel lblCity = new JLabel( "City" );
        JLabel lblZipCode = new JLabel( "Zip Code" );
        JLabel lblPhone = new JLabel( "Phone" );
        JLabel lblEmailID = new JLabel( "Emain Id" );

        JTextField tfFirstName = new JTextField();
        JTextField tfLastName = new JTextField();
        JTextField tfAddress = new JTextField();
        JTextField tfCity = new JTextField();
        JTextField tfZipCode = new JTextField();
        JTextField tfPhone = new JTextField();
        JTextField tfEmailID = new JTextField();

        lblFirstName.setBounds( 25, 55, 85, 20 );
        tfFirstName.setBounds( 25, 85, 85, 20 );
        tfFirstName.addFocusListener( l );
        pnlPjDetail.add( lblFirstName );
        pnlPjDetail.add( tfFirstName );

        lblLastName.setBounds( 25, 115, 85, 20 );
        tfLastName.setBounds( 25, 145, 85, 20 );
        tfLastName.addFocusListener( l );
        pnlPjDetail.add( lblLastName );
        pnlPjDetail.add( tfLastName );

        lblAddress.setBounds( 25, 175, 85, 20 );
        tfAddress.setBounds( 25, 205, 85, 20 );
        tfAddress.addFocusListener( l );
        pnlPjDetail.add( lblAddress );
        pnlPjDetail.add( tfAddress );

        lblCity.setBounds( 25, 55, 85, 20 );
        tfCity.setBounds( 25, 85, 85, 20 );
        tfCity.addFocusListener( l );
        pnlPjDetail2.add( lblCity );
        pnlPjDetail2.add( tfCity );

        lblZipCode.setBounds( 25, 115, 85, 20 );
        tfZipCode.setBounds( 25, 145, 85, 20 );
        tfZipCode.addFocusListener( l );
        pnlPjDetail2.add( lblZipCode );
        pnlPjDetail2.add( tfZipCode );

        lblPhone.setBounds( 25, 175, 85, 20 );
        tfPhone.setBounds( 25, 205, 85, 20 );
        tfPhone.addFocusListener( l );
        pnlPjDetail2.add( lblPhone );
        pnlPjDetail2.add( tfPhone );

        lblEmailID.setBounds( 25, 235, 85, 20 );
        tfEmailID.setBounds( 25, 265, 85, 20 );
        tfEmailID.addFocusListener( l );
        pnlPjDetail2.add( lblEmailID );
        pnlPjDetail2.add( tfEmailID );

        scrPjDetail = new JScrollPane( pnlPjDetail );
        scrPjDetail2 = new JScrollPane( pnlPjDetail2 );

        scrPjDetail.setAutoscrolls( true );

        //frmtest.setContentPane(scrProjectDetail);
        JSplitPane splitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, scrPjDetail, scrPjDetail2 );
        splitPane.setDividerLocation( 300 );
        interFrame.setContentPane( splitPane );
        interFrame.setVisible( true );

        //frmtest.getLayeredPane().add(interFrame);
        frmtest.setContentPane( interFrame );
        //frmtest.add(scrProjectDetail);
        frmtest.setVisible( true );
        frmtest.setResizable( false );
        frmtest.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        //return pnlPjDetail;       
    }

    public class SrcollListener implements FocusListener {

        @Override
        public void focusGained( FocusEvent e ) {
            final Component component = e.getComponent();
            if( component != null && component.getParent() != null && component.getParent() instanceof JComponent ) {
                SwingUtilities.invokeLater( new Runnable() {
                    @Override
                    public void run() {
                        ((JComponent)component.getParent()).scrollRectToVisible( component.getBounds() );
                    }
                } );
            }
        }

        @Override
        public void focusLost( FocusEvent e ) {
        }
    }
}
0 голосов
/ 29 августа 2011

Относительно вашего вопроса прокрутки: например, вы можете добавить слушателя, чтобы сфокусировать события и соответственно прокрутить панель.

FocusAdapter scrollFocusListener = new FocusAdapter() {
@Override
    public void focusGained(FocusEvent e) {
        System.out.println(((JComponent) e.getSource()).getBounds());
        scrPjDetail.getViewport().scrollRectToVisible(((JComponent) e.getSource()).getBounds());
    }
};
tfFirstName.addFocusListener(scrollFocusListener);
tfLastName.addFocusListener(scrollFocusListener);
tfAddress.addFocusListener(scrollFocusListener);
...
...