为jTabbedPane设置光标';java中的s选项卡

为jTabbedPane设置光标';java中的s选项卡,java,swing,cursor,focus,jtabbedpane,Java,Swing,Cursor,Focus,Jtabbedpane,我已经创建了一个自定义的jTabbedPane类,该类扩展了BasicTabbedPaneUI,并成功地创建了所需的jTabbedPane,但现在的问题是如何为自定义jTabbedPane中的每个选项卡设置手动光标 我试着用这个设置光标 tabbedPane.setUI(new CustomMainMenuTabs()); tabbedPane.setCursor(new Cursor((Cursor.HAND_CURSOR))); 这将为整个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或任何其他组件上时,如何将光标设置为手动光标。如果没有鼠标监听器,那就太好了

我想在鼠标移动到任何选项卡上时设置光标

我想您需要在选项卡式窗格中添加MouseMotionListener。然后,当生成
mouseMoved(…)
事件时,检查鼠标是否在选项卡上

您应该能够使用
BasicTabbePaneUI
tabForCoordinate(…)
方法来确定鼠标是否在选项卡上。

步骤:
  • 创建一个
    MouseMotionListener
    并将其添加到
    JTabbedPane
  • 在listener->mouseMoved方法中,检查鼠标的当前位置是否在选项卡的边界内
    • 如果为true,则将光标更改为手动光标
    • 否则显示默认光标
1.检查鼠标是否在选项卡边界内的方法: 3.要将侦听器添加到JTabbedPane,请执行以下操作: 相关文件:
最终代码: 将所有的PEICE放在一起,可以得到以下结果:

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;
    }
}
导入java.awt.Color;
导入java.awt.Cursor;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseMotionAdapter;
导入java.awt.event.MouseMotionListener;
导入java.awt.geom.Rectangle2D;
导入java.awt.geom.RoundRectangle2D;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JTabbedPane;
导入javax.swing.plaf.basic.BasicTabbedPaneUI;
公共级HAAMS{
//我的jTabbedPane自定义类
公共静态类CustomMainMenuTabs扩展了BasicTabbedPaneUI{
受保护的void paintTabBackground(图形g、int tabPlacement、,
int tabIndex、int x、int y、int w、int h、布尔值(已选择){
图形2d g2=(图形2d)g;
颜色;
如果(当选){
颜色=新颜色(74、175、211);
}else if(getRolloverTab()==tabIndex){
颜色=新颜色(45、145、180);
}否则{
颜色=新颜色(68,67,67);
}
g2.设置油漆(颜色);
g2.填充(新的圆形矩形2D.双(x,y,w,h,30,30));
g2.填充(新矩形2D.双(x+100,y,w,h));
}
}
公共静态void main(字符串[]args){
JFrame主屏幕=新JFrame(“自定义JTabbedPane”);
MainScreen.setExtendedState(MainScreen.getExtendedState())
|JFrame.MAXIMIZED_两者);
JTabbedPane jtpane=新JTabbedPane(2);
setUI(新的CustomMainMenuTabs());
MouseMotionListener侦听器=新建MouseMotionAdapter(){
public void mouseMoved(MouseEvent e){
JTabbedPane选项卡bedpane=(JTabbedPane)e.getSource();
如果(findTabPaneIndex(e.getPoint(),选项卡窗格)>-1){
tabbedPane.setCursor(新光标((Cursor.HAND_光标));
}否则{
tabbedPane.setCursor(新光标((Cursor.DEFAULT_Cursor));
}
}
};
jtpane.add(“第一个选项卡”,新的JPanel());
jtpane.add(“第二个选项卡”,新的JPanel());
jtpane.add(“第三个选项卡”,新的JPanel());
jtpane.addMouseMotionListener(listener);
MainScreen.getContentPane().add(jtpane);
MainScreen.setVisible(真);
}
私有静态int findTabPaneIndex(点p,JTabbedPane选项卡窗格){
对于(int i=0;i
您可以使用:

public void setTabComponentAt(int index,
                     Component component)
然后你就这么做了

component.addMouseListener(yourListener)

我已经根据您的需要更改了主要方法,手动光标将仅在选项卡标题上可见。检查它是否解决了您的问题

工作代码

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);
}
短期

只需将此代码添加到您的
CustomMainMenuTables

  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
,因此可以简单地扩展绘制滚动选项卡的机制,而无需使用更多侦听器或自己计算坐标

滚动是自Java5以来就出现在组件中的一种机制,这是一个适当的扩展,只需要重写和扩展该方法。每当鼠标在选项卡组件中移动时(它会影响选项卡区域,但不会影响子项),就会调用此方法并保持更新


我尝试过你的代码片段,效果很好。

这实际上比安装自定义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);
            }
        });
    }
}

我在这里看到了很多太复杂的答案(自定义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);
    }
  }
}

您需要在UI中提供鼠标支持。简单地添加一个鼠标侦听器,它可以在
  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);
    }
  }
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);
            }
        });
    }
}
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);
    }
  }
}