2013-05-04 75 views
1

我想要自定义JScrollBar设计。我使用Mac来开发Eclipse的应用程序。我已经尝试scrollPane.getVerticalScrollBar().setBackground(Color.BLACK);但没有发生。Java JScrollBar设计

我的代码:

scrollPane = new JScrollPane(scriptView); 
scrollPane.setBorder(BorderFactory.createEmptyBorder()); 
scrollPane.getVerticalScrollBar().setUnitIncrement(6); 
window.getContentPane().add(scrollPane); 

的对象scriptView是从类JEditorPane

应该怎么看:

sample

感谢每一个帮助。

+0

*“它应该看起来如何:”*我不明白。我在屏幕截图中看到** no **滚动条。 – 2013-05-04 11:13:25

+1

@AndrewThompson提出了一个关于可见性和可用性的关键问题,您应该在ScrollBarUI设计中考虑这个问题。 – trashgod 2013-05-04 12:38:44

回答

7

我想你正在寻找一个透明的滚动条。

enter image description here

这仅仅表现为一个想法(未测试的代码):

import java.awt.*; 
import javax.swing.*; 
import javax.swing.border.*; 
import javax.swing.plaf.basic.*; 

public class TranslucentScrollBarTest { 
    public JComponent makeUI() { 
    JTextArea cmp = new JTextArea(); 
    String str = "1234567890abcdefghijklmnopqrstuvwxyz"; 
    for(int i=0; i<20; i++) { 
     cmp.append(str+str+"\n"); 
    } 
    cmp.setForeground(Color.WHITE); 
    cmp.setBackground(Color.BLACK); 
    cmp.setOpaque(true); 

    JScrollPane scrollPane = new JScrollPane(
     cmp, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, 
     ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
    scrollPane.setComponentZOrder(scrollPane.getVerticalScrollBar(), 0); 
    scrollPane.setComponentZOrder(scrollPane.getViewport(), 1); 
    scrollPane.getVerticalScrollBar().setOpaque(false); 

    scrollPane.setLayout(new ScrollPaneLayout() { 
     @Override 
     public void layoutContainer(Container parent) { 
     JScrollPane scrollPane = (JScrollPane)parent; 

     Rectangle availR = scrollPane.getBounds(); 
     availR.x = availR.y = 0; 

     Insets insets = parent.getInsets(); 
     availR.x = insets.left; 
     availR.y = insets.top; 
     availR.width -= insets.left + insets.right; 
     availR.height -= insets.top + insets.bottom; 

     Rectangle vsbR = new Rectangle(); 
     vsbR.width = 12; 
     vsbR.height = availR.height; 
     vsbR.x = availR.x + availR.width - vsbR.width; 
     vsbR.y = availR.y; 

     if(viewport != null) { 
      viewport.setBounds(availR); 
     } 
     if(vsb != null) { 
      vsb.setVisible(true); 
      vsb.setBounds(vsbR); 
     } 
     } 
    }); 
    scrollPane.getVerticalScrollBar().setUI(new BasicScrollBarUI() { 
     private final Dimension d = new Dimension(); 
     @Override protected JButton createDecreaseButton(int orientation) { 
     return new JButton() { 
      @Override public Dimension getPreferredSize() { 
      return d; 
      } 
     }; 
     } 
     @Override protected JButton createIncreaseButton(int orientation) { 
     return new JButton() { 
      @Override public Dimension getPreferredSize() { 
      return d; 
      } 
     }; 
     } 
     @Override 
     protected void paintTrack(Graphics g, JComponent c, Rectangle r) {} 
     @Override 
     protected void paintThumb(Graphics g, JComponent c, Rectangle r) { 
     Graphics2D g2 = (Graphics2D)g.create(); 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
          RenderingHints.VALUE_ANTIALIAS_ON); 
     Color color = null; 
     JScrollBar sb = (JScrollBar)c; 
     if(!sb.isEnabled() || r.width>r.height) { 
      return; 
     }else if(isDragging) { 
      color = new Color(200,200,100,200); 
     }else if(isThumbRollover()) { 
      color = new Color(255,255,100,200); 
     }else { 
      color = new Color(220,220,200,200); 
     } 
     g2.setPaint(color); 
     g2.fillRoundRect(r.x,r.y,r.width,r.height,10,10); 
     g2.setPaint(Color.WHITE); 
     g2.drawRoundRect(r.x,r.y,r.width,r.height,10,10); 
     g2.dispose(); 
     } 
     @Override 
     protected void setThumbBounds(int x, int y, int width, int height) { 
     super.setThumbBounds(x, y, width, height); 
     scrollbar.repaint(); 
     } 
    }); 
    return scrollPane; 
    } 
    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    } 
    public static void createAndShowGUI() { 
    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    f.getContentPane().add(new TranslucentScrollBarTest().makeUI()); 
    f.setSize(320, 240); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 
} 
+0

不幸的是,提出的解决方案将打破JTable,并不会显示表头。 – ron190 2015-11-14 15:59:25

1

这里是一个改进版本,我做了一个私人项目。它也支持水平滚动条。

代码:

import javax.swing.*; 
import javax.swing.plaf.basic.BasicScrollBarUI; 

import java.awt.*; 

/** 
* This is an implementation of a JScrollPane with a modern UI 
* 
* @author Philipp Danner 
* 
*/ 
public class ModernScrollPane extends JScrollPane { 

    private static final long serialVersionUID = 8607734981506765935L; 

    private static final int SCROLL_BAR_ALPHA_ROLLOVER = 100; 
    private static final int SCROLL_BAR_ALPHA = 50; 
    private static final int THUMB_SIZE = 8; 
    private static final int SB_SIZE = 10; 
    private static final Color THUMB_COLOR = Color.Black; 

    public ModernScrollPane(Component view) { 
     this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED); 
    } 

    public ModernScrollPane(int vsbPolicy, int hsbPolicy) { 
     this(null, vsbPolicy, hsbPolicy); 
    } 

    public ModernScrollPane(Component view, int vsbPolicy, int hsbPolicy) { 

     setBorder(null); 

     // Set ScrollBar UI 
     JScrollBar verticalScrollBar = getVerticalScrollBar(); 
     verticalScrollBar.setOpaque(false); 
     verticalScrollBar.setUI(new ModernScrollBarUI(this)); 

     JScrollBar horizontalScrollBar = getHorizontalScrollBar(); 
     horizontalScrollBar.setOpaque(false); 
     horizontalScrollBar.setUI(new ModernScrollBarUI(this)); 

     setLayout(new ScrollPaneLayout() { 
      private static final long serialVersionUID = 5740408979909014146L; 

      @Override 
      public void layoutContainer(Container parent) { 
       Rectangle availR = ((JScrollPane) parent).getBounds(); 
       availR.x = availR.y = 0; 

       // viewport 
       Insets insets = parent.getInsets(); 
       availR.x = insets.left; 
       availR.y = insets.top; 
       availR.width -= insets.left + insets.right; 
       availR.height -= insets.top + insets.bottom; 
       if (viewport != null) { 
        viewport.setBounds(availR); 
       } 

       boolean vsbNeeded = isVerticalScrollBarfNecessary(); 
       boolean hsbNeeded = isHorizontalScrollBarNecessary(); 

       // vertical scroll bar 
       Rectangle vsbR = new Rectangle(); 
       vsbR.width = SB_SIZE; 
       vsbR.height = availR.height - (hsbNeeded ? vsbR.width : 0); 
       vsbR.x = availR.x + availR.width - vsbR.width; 
       vsbR.y = availR.y; 
       if (vsb != null) { 
        vsb.setBounds(vsbR); 
       } 

       // horizontal scroll bar 
       Rectangle hsbR = new Rectangle(); 
       hsbR.height = SB_SIZE; 
       hsbR.width = availR.width - (vsbNeeded ? hsbR.height : 0); 
       hsbR.x = availR.x; 
       hsbR.y = availR.y + availR.height - hsbR.height; 
       if (hsb != null) { 
        hsb.setBounds(hsbR); 
       } 
      } 
     }); 

     // Layering 
     setComponentZOrder(getVerticalScrollBar(), 0); 
     setComponentZOrder(getHorizontalScrollBar(), 1); 
     setComponentZOrder(getViewport(), 2); 

     viewport.setView(view); 
    } 
    private boolean isVerticalScrollBarfNecessary() { 
     Rectangle viewRect = viewport.getViewRect(); 
     Dimension viewSize = viewport.getViewSize(); 
     return viewSize.getHeight() > viewRect.getHeight(); 
    } 

    private boolean isHorizontalScrollBarNecessary() { 
     Rectangle viewRect = viewport.getViewRect(); 
     Dimension viewSize = viewport.getViewSize(); 
     return viewSize.getWidth() > viewRect.getWidth(); 
    } 

    /** 
    * Class extending the BasicScrollBarUI and overrides all necessary methods 
    */ 
    private static class ModernScrollBarUI extends BasicScrollBarUI { 

     private JScrollPane sp; 

     public ModernScrollBarUI(ModernScrollPane sp) { 
      this.sp = sp; 
     } 

     @Override 
     protected JButton createDecreaseButton(int orientation) { 
      return new InvisibleScrollBarButton(); 
     } 

     @Override 
     protected JButton createIncreaseButton(int orientation) { 
      return new InvisibleScrollBarButton(); 
     } 

     @Override 
     protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) { 
     } 

     @Override 
     protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { 
      int alpha = isThumbRollover() ? SCROLL_BAR_ALPHA_ROLLOVER : SCROLL_BAR_ALPHA; 
      int orientation = scrollbar.getOrientation(); 
      int x = thumbBounds.x; 
      int y = thumbBounds.y; 

      int width = orientation == JScrollBar.VERTICAL ? THUMB_SIZE : thumbBounds.width; 
      width = Math.max(width, THUMB_SIZE); 

      int height = orientation == JScrollBar.VERTICAL ? thumbBounds.height : THUMB_SIZE; 
      height = Math.max(height, THUMB_SIZE); 

      Graphics2D graphics2D = (Graphics2D) g.create(); 
      graphics2D.setColor(new Color(THUMB_COLOR.getRed(), THUMB_COLOR.getGreen(), THUMB_COLOR.getBlue(), alpha)); 
      graphics2D.fillRect(x, y, width, height); 
      graphics2D.dispose(); 
     } 

     @Override 
     protected void setThumbBounds(int x, int y, int width, int height) { 
      super.setThumbBounds(x, y, width, height); 
      sp.repaint(); 
     } 

     /** 
     * Invisible Buttons, to hide scroll bar buttons 
     */ 
     private static class InvisibleScrollBarButton extends JButton { 

      private static final long serialVersionUID = 1552427919226628689L; 

      private InvisibleScrollBarButton() { 
       setOpaque(false); 
       setFocusable(false); 
       setFocusPainted(false); 
       setBorderPainted(false); 
       setBorder(BorderFactory.createEmptyBorder()); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setPreferredSize(new Dimension(400, 400)); 

     JPanel content = new JPanel(); 
     content.setBackground(Color.WHITE); 
     content.setPreferredSize(new Dimension(500, 500)); 
     content.add(new JLabel("test")); 
     frame.add(new ModernScrollPane(content)); 

     frame.pack(); 
     frame.setVisible(true); 
    } 
} 
0

可悲的是提出的解决方案将打破JTable中并不会显示表头,但我发现this solution,似乎工作。