在java中为jTabbedPane选项卡设置游标

时间:2014-09-22 15:04:28

标签: java swing cursor focus jtabbedpane

我创建了一个自定义jTabbedPane类,它扩展了BasicTabbedPaneUI并成功创建了我想要的jTabbedPane但现在的问题是如何为我的自定义中的每个标签设置手形光标的 JTabbedPane的

我尝试用这个

设置光标
tabbedPane.setUI(new CustomMainMenuTabs());
tabbedPane.setCursor(new Cursor((Cursor.HAND_CURSOR)));

这为整个jTabbedPane设置了光标,但是当鼠标悬停在其中任何一个选项卡上时我想设置光标。

如何在jTabbedPane中为标签设置手形光标?

我的代码是

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import javax.swing.plaf.basic.BasicTabbedPaneUI;


public class HAAMS 
{
  //My Custom class for jTabbedPane
  public static class CustomMainMenuTabs extends BasicTabbedPaneUI
  {
    protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
        Graphics2D g2 = (Graphics2D) g;

        Color color;

        if (isSelected) { color = new Color(74, 175, 211); } 
        else if (getRolloverTab() == tabIndex) {  color = new Color(45, 145, 180); } 
        else {color = new Color(68, 67, 67);}

        g2.setPaint(color);
        g2.fill(new RoundRectangle2D.Double(x, y, w, h, 30, 30));

        g2.fill(new Rectangle2D.Double(x + 100,y,w,h));
    }
  }

   public static void main(String[] args) 
   {
     JFrame MainScreen = new JFrame("Custom JTabbedPane");
     MainScreen.setExtendedState(MainScreen.getExtendedState() | JFrame.MAXIMIZED_BOTH);

     //Setting UI for my jTabbedPane implementing my custom class CustomMainMenuTabs
     JTabbedPane jtpane = new JTabbedPane(2);
     jtpane.setUI(new CustomMainMenuTabs());
     jtpane.add("1st Tabe", new JPanel());
     jtpane.add("2nd Tabe", new JPanel());
     jtpane.add("3rd Tabe", new JPanel());

     MainScreen.getContentPane().add(jtpane);
     MainScreen.setVisible(true);
  }
}

当鼠标悬停在任何标签上而不是jpanel或任何其他组件时,如何将光标设置为HAND_CURSOR光标。如果没有鼠标监听器就会很棒。

7 个答案:

答案 0 :(得分:3)

我在这里看到很多答案太复杂了(自定义UI,额外的听众,图形资料等)。

基本上,camickr为你拼出来了。这是一个简单的演示:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;

public class JTabbedPaneCursorDemo implements Runnable
{
  JTabbedPane tabbedPane;

  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new JTabbedPaneCursorDemo());
  }

  public void run()
  {
    JPanel panelA = new JPanel();
    JPanel panelB = new JPanel();

    tabbedPane = new JTabbedPane();
    tabbedPane.addTab("A", panelA);
    tabbedPane.addTab("B", panelB);

    tabbedPane.addMouseMotionListener(new MouseMotionListener()
    {
      public void mouseDragged(MouseEvent e) {}

      public void mouseMoved(MouseEvent e)
      {
        adjustCursor(e);
      }
    });

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 200);
    frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }

  private void adjustCursor(MouseEvent e)
  {
    TabbedPaneUI ui = tabbedPane.getUI();
    int index = ui.tabForCoordinate(tabbedPane, e.getX(), e.getY());

    if (index >= 0)
    {
      tabbedPane.setCursor(new Cursor((Cursor.HAND_CURSOR)));
    }
    else
    {
      tabbedPane.setCursor(null);
    }
  }
}

答案 1 :(得分:2)

  

我想在鼠标移过其中的任何标签时设置光标。

我猜你需要将一个MouseMotionListener添加到选项卡式窗格。然后,当生成mouseMoved(...)事件时,检查鼠标是否在选项卡上。

您应该可以使用tabForCoordinate(...)的{​​{1}}方法来判断鼠标是否在标签上。

答案 2 :(得分:0)

步骤:

  • 创建MouseMotionListener并将其添加到您的JTabbedPane
  • 听众内部 - > mouseMoved方法,chec kif鼠标的当前位置在选项卡的边界内
    • 如果为true,则将光标更改为手形光标
    • else显示默认光标

1.方法检查鼠标是否在标签的范围内:

private static int findTabPaneIndex(Point p, JTabbedPane tabbedPane) {
    for (int i = 0; i < tabbedPane.getTabCount(); i++) {
        if (tabbedPane.getBoundsAt(i).contains(p.x, p.y)) {
            return i;
        }
    }
    return -1;
}

2.小鼠听众:

    MouseMotionListener listener = new MouseMotionAdapter() {
        public void mouseMoved(MouseEvent e) {
            JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
            if (findTabPaneIndex(e.getPoint(), tabbedPane) > -1) {
                tabbedPane.setCursor(new Cursor((Cursor.HAND_CURSOR)));
            } else {
                tabbedPane.setCursor(new Cursor((Cursor.DEFAULT_CURSOR)));
            }
        }
    };

3.将侦听器添加到JTabbedPane:

    jtpane.addMouseMotionListener(listener);

相关文档:

最终代码:

将所有的peices放在一起,你会得到以下结果:

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.plaf.basic.BasicTabbedPaneUI;

public class HAAMS {
    // My Custom class for jTabbedPane
    public static class CustomMainMenuTabs extends BasicTabbedPaneUI {
        protected void paintTabBackground(Graphics g, int tabPlacement,
                int tabIndex, int x, int y, int w, int h, boolean isSelected) {
            Graphics2D g2 = (Graphics2D) g;
            Color color;
            if (isSelected) {
                color = new Color(74, 175, 211);
            } else if (getRolloverTab() == tabIndex) {
                color = new Color(45, 145, 180);
            } else {
                color = new Color(68, 67, 67);
            }
            g2.setPaint(color);
            g2.fill(new RoundRectangle2D.Double(x, y, w, h, 30, 30));
            g2.fill(new Rectangle2D.Double(x + 100, y, w, h));
        }
    }

    public static void main(String[] args) {
        JFrame MainScreen = new JFrame("Custom JTabbedPane");
        MainScreen.setExtendedState(MainScreen.getExtendedState()
                | JFrame.MAXIMIZED_BOTH);
        JTabbedPane jtpane = new JTabbedPane(2);
        jtpane.setUI(new CustomMainMenuTabs());
        MouseMotionListener listener = new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
                if (findTabPaneIndex(e.getPoint(), tabbedPane) > -1) {
                    tabbedPane.setCursor(new Cursor((Cursor.HAND_CURSOR)));
                } else {
                    tabbedPane.setCursor(new Cursor((Cursor.DEFAULT_CURSOR)));
                }
            }
        };
        jtpane.add("1st Tabe", new JPanel());
        jtpane.add("2nd Tabe", new JPanel());
        jtpane.add("3rd Tabe", new JPanel());
        jtpane.addMouseMotionListener(listener);
        MainScreen.getContentPane().add(jtpane);
        MainScreen.setVisible(true);
    }

    private static int findTabPaneIndex(Point p, JTabbedPane tabbedPane) {
        for (int i = 0; i < tabbedPane.getTabCount(); i++) {
            if (tabbedPane.getBoundsAt(i).contains(p.x, p.y)) {
                return i;
            }
        }
        return -1;
    }
}

答案 3 :(得分:0)

您可以使用:

public void setTabComponentAt(int index,
                     Component component)

然后你做

component.addMouseListener(yourListener)

答案 4 :(得分:0)

我已根据您的需要更改了主要方法,手形光标仅在标题页上可见。检查它是否解决了你的问题

工作代码

public static void main(String[] args)
{
    JFrame MainScreen = new JFrame("Custom JTabbedPane");
    MainScreen.setExtendedState(MainScreen.getExtendedState() | JFrame.MAXIMIZED_BOTH);

    MouseListener listener = new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            JTabbedPane jp=(JTabbedPane)(e.getComponent().getParent().getParent());
            jp.setSelectedIndex(jp.indexAtLocation(e.getComponent().getX(),e.getComponent().getY()));
       }

        @Override
        public void mouseEntered(MouseEvent e) {
            e.getComponent().setCursor(new Cursor((Cursor.HAND_CURSOR)));
        }


    };

    JLabel jlabel1=new JLabel("1st Tabe");
    jlabel1.addMouseListener(listener);
    JLabel jlabel2=new JLabel("2nd Tabe");
   jlabel2.addMouseListener(listener);
    JLabel jlabel3=new JLabel("3rd Tabe");
   jlabel3.addMouseListener(listener);

    //Setting UI for my jTabbedPane implementing my custom class CustomMainMenuTabs
    JTabbedPane jtpane = new JTabbedPane(2);

   jtpane.setUI(new CustomMainMenuTabs());
    jtpane.add("1st Tabe", new JPanel());
    jtpane.setTabComponentAt( 0, jlabel1);
    jtpane.add("2nd  Tabe", new JPanel());
    jtpane.setTabComponentAt(1, jlabel2);
    jtpane.add("3rd  Tabe", new JPanel());
    jtpane.setTabComponentAt( 2, jlabel3);




    MainScreen.getContentPane().add(jtpane);
    MainScreen.setVisible(true);
}

答案 5 :(得分:0)

<强>短

只需将此代码添加到CustomMainMenuTabs

即可
  public static class CustomMainMenuTabs extends BasicTabbedPaneUI
  {
    protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
    // ...
    }
    private static final Cursor DEFAULT_CURSOR = Cursor.getDefaultCursor();
    private static final Cursor HAND_CURSOR = new Cursor((Cursor.HAND_CURSOR));
    protected void setRolloverTab(int index) {
        tabPane.setCursor((index != -1) ? HAND_CURSOR : DEFAULT_CURSOR);
        super.setRolloverTab(index);
    }
  }

<强>解释

由于你已经扩展BasicTabbedPaneUI,你可以简单地扩展绘制翻转标签的机制,这已经在那里实现,而无需使用更多的监听器或自己计算坐标。

滚动是一个自Java 5以来一直存在于组件中的机制,这是一个适当的扩展,只需要覆盖和扩展该方法。只要鼠标在标签组件中移动(它会影响标签区域但不影响子项),就会调用此方法,并且它会不断更新。

我已尝试使用此添加的代码段并且工作正常。

答案 6 :(得分:0)

它实际上比安装自定义UI委托容易得多。

您可以将自己的标签安装为标签组件(标签手柄内的组件),它们将有自己的光标。以下是一个简单示例,其中包含3个选项卡,以及用于选项卡式窗格主体和每个选项卡的不同光标:

import java.awt.*;
import javax.swing.*;

public class TestTabCursor extends JFrame {

    private JTabbedPane contentPane;

    public TestTabCursor() {
        super("Test tab cursor");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(640, 480);
        setLocation(100, 100);
        createContentPane();        
        setCursors();
    }

    private void createContentPane() {
        contentPane = new JTabbedPane();

        addTab(contentPane);
        addTab(contentPane);
        addTab(contentPane);

        setContentPane(contentPane);
    }

    private void addTab(JTabbedPane tabbedPane) {
        int index = tabbedPane.getTabCount() + 1;

        JLabel label = new JLabel("Panel #" + index);
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setFont(label.getFont().deriveFont(72f));

        JPanel panel = new JPanel(new BorderLayout());
        panel.setBackground(Color.white);
        panel.add(label, BorderLayout.CENTER);

        JLabel title = new JLabel("Tab " + index);

        tabbedPane.add(panel);
        tabbedPane.setTabComponentAt(index - 1, title);
    }

    private void setCursors() {
        contentPane.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));

        contentPane.getTabComponentAt(0).setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        contentPane.getTabComponentAt(1).setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
        contentPane.getTabComponentAt(2).setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));     
    }

    public static void main(String... args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new TestTabCursor();
                frame.setVisible(true);
            }
        });
    }
}