I want to have a JInternalFrame that will be able to handle JTabbedPane much like the Eclipse IDE. I want the tabs to sit on top of the title bar. Each tab should have its own close button. The InternalFrame should also have a close button so that a user can close all the tabs in one go.
This is what I have:
This is what I want to have (screenshot taken from Eclipse IDE):
I don't know how I can achieve this. Can anyone please point me in the right direction?
EDIT:
Based on a comment to look into UI Delegate, I created a UI delegate subclass that is able to remove the menu, but there are some problems with this:
It looks kind of funny in comparison to a normal JInternalFrame, even though I haven't done anything to it but comment out the "createActionMap" and "add(menuBar)" lines.
I can't find anywhere in the library code to indicate how the title bar and contentPane positions are set - obviously I want to move the position of the contentPane to overlap the title bar.
Here are the codes:
public class MyInternalFrameUI extends BasicInternalFrameUI {
public MyInternalFrameUI(JInternalFrame b) {
super(b);
// TODO Auto-generated constructor stub
}
public static ComponentUI createUI(JComponent b) {
return new MyInternalFrameUI((JInternalFrame)b);
}
protected JComponent createNorthPane(JInternalFrame w) {
titlePane = new MyBasicInternalFrameTitlePane(w);
return titlePane;
}
}
public class MyBasicInternalFrameTitlePane extends BasicInternalFrameTitlePane {
public MyBasicInternalFrameTitlePane(JInternalFrame f) {
super(f);
}
protected void installTitlePane() {
installDefaults();
installListeners();
createActions();
enableActions();
//createActionMap(); // This method is package protected and not visible
setLayout(createLayout());
assembleSystemMenu();
createButtons();
addSubComponents();
}
protected void addSubComponents() {
//add(menuBar); // Remove this to disable the menu
add(iconButton);
add(maxButton);
add(closeButton);
}
}
To answer one part with the close button. A solution is to add the close button yourself (there is no option for that built in Swing).
You have to implement the closeTab(…) method or a better solution would be a callback handler
protected class CloseTabButton extends JPanel {
private JLabel titleLabel;
protected CloseTabButton(JTabbedPane aTabbedPane,
final AbstractObservableObjectJPanel<M> aDetailPanel,
String aTitle, Icon anIcon) {
setOpaque(false);
titleLabel = new JLabel(aTitle, anIcon, JLabel.LEFT);
add(titleLabel);
ImageIcon closeImage = new ImageIcon(
CloseTabButton.class.getResource("/images/icon_normal.png"));
Image img = closeImage.getImage();
Image newimg = img.getScaledInstance(16, 16,
java.awt.Image.SCALE_SMOOTH);
ImageIcon closeIcon = new ImageIcon(newimg);
ImageIcon closeImageRollover = new ImageIcon(
CloseTabButton.class.getResource("/images/icon_roll.png"));
Image imgRoll = closeImageRollover.getImage();
Image newimgRoll = imgRoll.getScaledInstance(16, 16,
java.awt.Image.SCALE_SMOOTH);
ImageIcon closeIconRoll = new ImageIcon(newimgRoll);
JButton btClose = new JButton(closeIcon);
btClose.setPreferredSize(new Dimension(15, 15));
add(btClose);
btClose.setOpaque(false);
btClose.setContentAreaFilled(false);
btClose.setBorderPainted(false);
btClose.setRolloverIcon(closeIconRoll);
btClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent aE) {
closeTab(aDetailPanel);
}
});
aTabbedPane.setTabComponentAt(
aTabbedPane.indexOfComponent(aDetailPanel), this);
}
public JLabel getTitleLabel() {
return titleLabel;
}
}
To add keyboard shortcuts you can add them to the input map via
KeyStroke ctrlW = KeyStroke.getKeyStroke(KeyEvent.VK_W,
InputEvent.CTRL_DOWN_MASK);
getRootPane()
.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.put(ctrlW, disposeAction.getValue(Action.NAME));
DisposeAction is just an Action that also calls closeTab(…)
Related
I am currently facing a small issue that goes like this: I have a button which, when clicked, will trigger the display of a JPopupMenu under it ( I grab the location of the button, substract a bit from it's height and display the JPopupMenu). This is all made in NetBeans with the GUI builder.
The JPopupMenu is composed of several JPanels, which contain a JLabel, a Button, a TextField and a CheckBox. Those JPanels, I want them to be first initialized in a "minimized" mode( display only the label), but, when the user clicks on them, to expand and display the other components as well. On a second click, the JPanel will revert to the "minimized" state.
Now, I don't know exactly where the issue is, whether in the way the JPanel is resized or not, but although when I click the button the popup menu is displayed correctly and everything else, if I expand a JPanel inside it, the popup menu does not get resized -> it has the same width/height no matter what I do. I tried to change the Layout Manager used by JPopupMenu to FlowLayout,BoxLayout, but ultimately they had no effect. Now, a few snippets of points of interest in the code:
public class WifiItem extends javax.swing.JPanel {
private final Dimension maxDimension;
private final Dimension minDimension;
private boolean maximized;
public WifiItem() {
initComponents();
setBorder(BorderFactory.createLineBorder(Color.black, 1));
maxDimension = new Dimension(386, 62);
minDimension = new Dimension(386, 32);
maximized = false;
setSize(minDimension);
setPreferredSize(minDimension);
setMinimumSize(minDimension);
setMaximumSize(minDimension);
this.setPreferredSize(minDimension);
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (maximized) {
setToMin();
} else {
setToMax();
}
}
});
}
public final void setToMax() {
setSize(maxDimension);
setPreferredSize(maxDimension);
setMinimumSize(maxDimension);
setMaximumSize(maxDimension);
maximized = true;
getParent().revalidate();
}
public final void setToMin() {
setSize(minDimension);
setPreferredSize(minDimension);
setMinimumSize(minDimension);
setMaximumSize(minDimension);
maximized = false;
getParent().revalidate();
}
This is where I build the JPopupMenu and set up the display.
public class WifiConnections {
private static final List<WifiItem> connectionsList = new ArrayList<>();
public static JPopupMenu displayPanel;
public WifiConnections() {
displayPanel = new JPopupMenu();
displayPanel.setLayout(new BoxLayout(displayPanel, BoxLayout.Y_AXIS));
WifiItem newItem = new WifiItem();
newItem.setConnectionId("Connection 1.");
WifiItem newItem2 = new WifiItem();
newItem2.setConnectionId("Connection 2.");
connectionsList.add(newItem);
connectionsList.add(newItem2);
connectionsList.forEach((item) -> {
displayPanel.add(item);
});
}
public void displayPopup(Point p) {
displayPanel.setLocation(p.x, p.y + 34);
displayPanel.setVisible(true);
}
public void hidePopup() {
displayPanel.setVisible(false);
}
}
As you can see, if I expand one item, the other one gets covered and the popup does not resize to fit the JPanels, and I am really at a loss at how to continue.
I have a few JComboBoxes in my programm. I want to change the size of the scrollbar and the arrow button in the way that they are much wider. I need that because I want to use the programm on a Windows tablet and it is too small for a finger to work with.
Is there any possibility to do that?
JComboBox comboBox;
comboBox = new JComboBox(list_apple_device.toArray());
comboBox.setSelectedItem(null);
comboBox.setFont(schrift);
comboBox.setBounds(1568, 329, 306, 43);
comboBox.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
// TODO Auto-generated method stub
textField.setText(""+e.getItem());
}
});
getContentPane().add(comboBox);
That's my code.
You can use the UIManger to control the width of the scrollbar:
UIManager.put("ScrollBar.width", new Integer(50));
You would execute that code BEFORE you create the combo box.
it's not so easy, but there is a solution, you have to subclass jcombobox...
You have to subclass JComboBox to get access to the ComboBoxUI. To do so you set your own custom ComboBoxUI during object instanciation (we make changes in the all constructors, see init() in CustomComboBox.
The ComboBoxUI is required to get access to the ComboboxPopup. We replace simply the default ComboboxPopup with our custom ComboboxPopup. You have to know that the ComboboxPopup is responsible for the creation of the drop-down-menu, that pops up when you click on the button.
then we finally can adjust the JScrollPane from the Popup, we grab the vertical JScrollBarand alter its appearance (setting a custom width).
public class CustomComboBox<T> extends JComboBox<T> {
public CustomComboBox() {
super();
init();
}
public CustomComboBox(ComboBoxModel<T> aModel) {
super(aModel);
init();
}
public CustomComboBox(T[] items) {
super(items);
init();
}
public CustomComboBox(Vector<T> items) {
super(items);
init();
}
public void init(){
CustomComboBoxUI ccbui = new CustomComboBoxUI();
setUI(ccbui);
}
}
this is the custom ComboboxUI that grants you acces to the ComboboxPopup (quite simple):
public class CustomComboBoxUI extends BasicComboBoxUI{
protected ComboPopup createPopup() {
return new CustomComboBoxPopup( comboBox );
}
}
thankgod the custom ComboboxPopup needs just the basic constructor overriden and only one method changed (sets the size of the scrollpan to 40px):
public class CustomComboBoxPopup extends BasicComboPopup{
public CustomComboBoxPopup(JComboBox combo) {
super(combo);
}
#Override
protected void configureScroller() {
super.configureScroller();
scroller.getVerticalScrollBar().setPreferredSize(new Dimension(40, 0));
}
}
to set the size of the combobox you simply need to adjust its size
String[] data = new String[]{"a","b","c","d","e","f","g","h","i"};
CustomComboBox<String> comboBox = new CustomComboBox(data);
comboBox.setPreferredSize(new Dimension(50,50)); //set the size you wish
see also setting size of scroller and setting size of combobox for further help...
How would I call an Action from another class in Java? I got a CloseTabButton class online that allows a simple close tab button on each JTabbedPane, but when the tab is closed, I would like a dialog to pop up based on information (if file is not saved, ask to save it, etc.). This is the file:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class CloseTabButton extends JPanel implements ActionListener {
private JTabbedPane pane;
public CloseTabButton(JTabbedPane pane, int index) {
this.pane = pane;
setOpaque(false);
// CloseIcon class just had a button with an x painted on it
Icon closeIcon = new CloseIcon();
JButton close = new JButton(closeIcon);
close.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()));
close.addActionListener(this);
add(new JLabel(pane.getTitleAt(index), pane.getIconAt(index), JLabel.LEFT));
add(close);
pane.setTabComponentAt(index, this);
}
#Override
public void actionPerformed(ActionEvent e) {
int i = pane.indexOfTabComponent(this);
String fileName = pane.getToolTipTextAt(i);
// Where I want to ask if user wants to save, etc.
if (fileName == "Untitled") {
// Do stuff
}
pane.remove(i); // Removes the tab
// If tab count < 1, then disable the save and save as buttons on menu
if (pane.getTabCount() < 1) {
JFrame frame = (JFrame) pane.getParent().getParent().getParent().getParent().getParent(); // Yes, there is that many in my code to get the parent JFrame
int menuCount = frame.getJMenuBar().getMenuCount();
for (int a = 0; a < menuCount; a++) {
int itemCount = frame.getJMenuBar().getMenu(a).getItemCount();
for (int b = 0; b < itemCount; b++) {
Component component = frame.getJMenuBar().getMenu(a).getMenuComponent(b);
if (!(component instanceof JSeparator)) {
// Not a seperator
String itemName = frame.getJMenuBar().getMenu(a).getItem(b).getAccessibleContext().getAccessibleName();
if (itemName == "Save As..") {
frame.getJMenuBar().getMenu(a).getItem(b).setEnabled(false);
}
}
}
}
}
}
}
In my main class I have actions listed like this:
static Action Close = new AbstractAction("Close") {
public void actionPerformed(ActionEvent e) {
closeCurrentWindow(); // function that will close tab
}
}
The other menu items are Actions as well, and as you can see, what I'm currently doing in the CloseTabButton class is quite frustrating, and most likely the wrong way to code it. Is there a much simpler way to do what I'm doing?
The first thing I might do is provide ActionListener support to the CloseTabButton, for example...
public class CloseTabButton extends JPanel {
private JTabbedPane pane;
public CloseTabButton(JTabbedPane pane, int index) {
this.pane = pane;
setOpaque(false);
// CloseIcon class just had a button with an x painted on it
Icon closeIcon = new CloseIcon();
JButton close = new JButton(closeIcon);
close.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()));
close.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fireActionPerformed();
}
});
add(new JLabel(pane.getTitleAt(index), pane.getIconAt(index), JLabel.LEFT));
add(close);
pane.setTabComponentAt(index, this);
}
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
public void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
protected void fireActionPerformed() {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "You could provide you own action command for each tab here");
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
}
Basically, this now allows you to register your own ActionListeners to the CloseTabButton
Next, this, fileName == "Untitled", is not how you compare Strings in Java, you should be using something more like "Untitled".equals(fileName)
If you're menus are based on actual Actions, then you can simply disable the Actions themselves. This would require a little bit of work, but a lot less of "guess" work then you're doing now.
Basically, you would monitor the JTabbedPane itself, monitoring for changes to the selected tab and updating the states of the individual Actions themselves
There a number of ways you could do this, like passing a reference of the JTabbedPane to the Actions so they can perform there own monitoring (but I'd use some kind of management interface which could more easily provide information to the Actions and decouple the code and the reliance on JTabbedPane directly, then you could be free to use JInternalFrames instead).
You could have a "menu manager" which did a similar job, monitoring changes to the document container and changing the state of the menu Actions based on the current state, as an example
Updated
If you're making use of the Action API (which I would recommend), then you could simply do something like...
public class CloseTabButton extends JPanel {
private JTabbedPane pane;
public CloseTabButton(JTabbedPane pane, Action action, int index) {
this.pane = pane;
setOpaque(false);
// CloseIcon class just had a button with an x painted on it
Icon closeIcon = new CloseIcon();
JButton close = new JButton(action);
close.setIcon(closeIcon);
close.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()));
add(new JLabel(pane.getTitleAt(index), pane.getIconAt(index), JLabel.LEFT));
add(close);
pane.setTabComponentAt(index, this);
}
}
Passing in the Action for the close operation, then use the same action for both the JMenuItem and JTabbedPane.
The "core" issue would be how you would identify the "current" tab and document in a uniform manner
Hi I want to make my JPanel disappear so I wrote these lines of code
removeAll();
updateUI();
revalidate();
That only made the JComponents and JButtons disappear. I would like to make the images that I have displayed with the paint method disappear also. If I do setVisible(false), then I cannot add another JPanel behind it.
This is my class:
package screens;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class menuScreen extends JPanel implements MouseListener{
private static final long serialVersionUID = 1L;
//-------------VARIABLES---------------//
Image wallpaper = (Image)Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/wallpaper.jpg"));
Image title_text = (Image)Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/title-text.png"));
ImageIcon startGameimg = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/startGame.png")));
ImageIcon optionsimg = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/options.png")));
//JButton start = new JButton(basketball);
JLabel options = new JLabel(optionsimg);
JLabel startGame = new JLabel(startGameimg);
gameScreen gS = new gameScreen();
CardLayout scenechange = new CardLayout();
JPanel scenechange1 = new JPanel (scenechange);
//-------------PAINT FUNCTION----------//
public void paintComponent(Graphics g){
g.drawImage(wallpaper,0,0,this);
g.drawImage(title_text,0,0,this);
//g.drawImage(basketball1,110,180,this);
}
//-------------CONSTRUCTOR-------------//
public menuScreen(){
scenechange.addLayoutComponent(this,"menuScreen");
scenechange.addLayoutComponent(gS,"gameScreen");
//scenechange.show(this,"menuScreen");
this.setLayout(null);
this.add(options);
this.add(startGame);
startGame.setBounds(110,180,110,110);
options.setBounds(110,300,110,110);
startGame.addMouseListener(this);
options.addMouseListener(this);
}
public void mouseClicked(MouseEvent e) {
if(e.getSource() == (startGame)){
removeAll();
revalidate();
add(gS);
}
if(e.getSource() == (options)){
setVisible(false);
}
}
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}//END OF CLASS startingScreen
Thanks in advance.
First, don't call updateUI, it's related to the Look and Feel and not (directly) to updating your components.
If you have provided a custom paint routine within in your panel, then you need away to stop it from painting the images (without preventing it from painting it's own content). removeXxx will remove child components that you have previously added to the container.
A little more code would be useful
UPDATE
Fisrt, the images your painting aren't components of you container, they are been "stamped", you need some way to tell the component not to the paint the images
public void paintComponent(Graphics g){
super.paintComponent(g); // this is super important
if (paintImages){ // you need to define and set this flag
g.drawImage(wallpaper,0,0,this);
g.drawImage(title_text,0,0,this);
}
}
Now, this will stop the images from been painted.
If, however, you no longer want to use the component (ie, you want to remove it from the screen so you can place a new component on the screen in its place), you need to remove this component from it's parent, which Code-Guru has suggested (so I won't steal his answer ;))
UPDATE
Okay, you had a kernel of an idea but either didn't quite know how to implement it or decided to discard it.
Basically, from the looks of your code, you were either trying to, or had, implement a CardLayout, unfortunately, you kind of got the wrong idea with it.
With CardLayout, you need to "controller", a component that is responsible for switching the screens...
public class ScreenController extends JPanel {
private static final long serialVersionUID = 1L;
//-------------VARIABLES---------------//
MenuScreen ms = new MenuScreen();
GameScreen gs = new GameScreen();
CardLayout sceneChange;
//-------------CONSTRUCTOR-------------//
public ScreenController() {
sceneChange = new CardLayout();
this.setLayout(sceneChange);
add(ms, "menuScreen");
add(gs, "gameScreen");
sceneChange.show(this, "menuScreen");
ms.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase("startgame")) {
sceneChange.show(ScreenController.this, "gameScreen");
}
}
});
}
}//END OF CLASS startingScreen
Then you have your menu and game screens...
public class MenuScreen extends JPanel implements MouseListener {
private static final long serialVersionUID = 1L;
//-------------VARIABLES---------------//
//JButton start = new JButton(basketball);
JLabel options = new JLabel("Options");
JLabel startGame = new JLabel(" >> Start << ");
// gameScreen gS = new gameScreen();
BufferedImage wallpaper;
//-------------PAINT FUNCTION----------//
#Override
public void paintComponent(Graphics g) {
System.out.println("paint");
super.paintComponent(g);
if (wallpaper != null) {
g.drawImage(wallpaper, 0, 0, this);
}
}
//-------------CONSTRUCTOR-------------//
public MenuScreen() {
// Please handle your exceptions better
try {
wallpaper = ImageIO.read(getClass().getResource("/Menu.png"));
setPreferredSize(new Dimension(wallpaper.getWidth(), wallpaper.getHeight()));
} catch (IOException ex) {
ex.printStackTrace();
}
setLayout(new GridBagLayout());
Cursor cusor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
options.setCursor(cusor);
startGame.setCursor(cusor);
Font font = UIManager.getFont("Label.font").deriveFont(Font.BOLD, 48);
options.setFont(font);
startGame.setFont(font);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
this.add(options, gbc);
gbc.gridy++;
this.add(startGame, gbc);
startGame.addMouseListener(this);
options.addMouseListener(this);
}
public void mouseClicked(MouseEvent e) {
if (e.getSource() == (startGame)) {
fireActionPerformed("startGame");
}
if (e.getSource() == (options)) {
fireActionPerformed("gameOptions");
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
public void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
protected void fireActionPerformed(String cmd) {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
if (listeners != null && listeners.length > 0) {
ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, cmd);
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
}
}
Menu Screen...
And when you click start...the game screen...
Now this is an EXAMPLE. Please try and take the time to understand what it going on in the code before you march ahead and implement it. I used by own images, you'll need to get your own..
There are several ways to stop your JPanel from "appearing" depending on exactly what you want to accomplish. One was it to to call setOpaque(false);. I'm not entirely sure how this affects custom painting, though.
Another posibility is
Container parent = getParent().remove(this);
parent.validate();
A third posibility is to add a flag in your class which is set when you click on a JLabel (or better yet a JButton -- see comments below). Then in your paintComponent() method you can check the flag and draw accordingly.
Note:
You are incorrectly using a JLabel and mouse events to respond to user input. Typically in a Swing application, we use JButtons and ActionListeners to accomplish what you are trying to do here. One advantage of this is that you only have to implement one method called onActionPerformed() and don't need to worry about adding all the mouse event handlers that you don't want to even respond to.
I would like to remove the scrollbar arrow buttons from a scrollbar in a JScrollPane. How would I do this?
class NoArrowScrollBarUI extends BasicScrollBarUI {
protected JButton createZeroButton() {
JButton button = new JButton("zero button");
Dimension zeroDim = new Dimension(0,0);
button.setPreferredSize(zeroDim);
button.setMinimumSize(zeroDim);
button.setMaximumSize(zeroDim);
return button;
}
#Override
protected JButton createDecreaseButton(int orientation) {
return createZeroButton();
}
#Override
protected JButton createIncreaseButton(int orientation) {
return createZeroButton();
}
#Override
protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) {
//own painting if needed
}
#Override
protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
//own painting if needed
}
}
Removing buttons let space for then. I found make buttons zero as the simplest way.
If you are using the basic version of JScrollBar, then it is probably rendering using the BasicScrollBarUI. I would suggest that you extend BasicScrollBarUI to create a custom UI class (like MyBasicScrollBarUI) . The buttons are protected variables in the superclass. So you need to override the installComponents() methods in the subclass and make sure that you do not add the buttons. See the below code snippet and hide the lines as suggested there.
protected void installComponents(){
switch (scrollbar.getOrientation()) {
case JScrollBar.VERTICAL:
incrButton = createIncreaseButton(SOUTH);
decrButton = createDecreaseButton(NORTH);
break;
case JScrollBar.HORIZONTAL:
if (scrollbar.getComponentOrientation().isLeftToRight()) {
incrButton = createIncreaseButton(EAST);
decrButton = createDecreaseButton(WEST);
} else {
incrButton = createIncreaseButton(WEST);
decrButton = createDecreaseButton(EAST);
}
break;
}
scrollbar.add(incrButton); // Comment out this line to hide arrow
scrollbar.add(decrButton); // Comment out this line to hide arrow
// Force the children's enabled state to be updated.
scrollbar.setEnabled(scrollbar.isEnabled());
}
Then, in your code after you initialize a JScrollBar, you can call setUI() and pass in an instance of MyBasicScrollBarUI class.
Note: I havent tried this myself, but from the code it looks like it could work.
It is not the most elegant way... but works for me
JScrollBar jsb = getHorizontalScrollBar();
for(Component c : jsb.getComponents()) {
jsb.remove(c);
}
This is the way i went.
Set the scrollbar policy of the scrollbar you want to hide as never
Mimic this behavior with a MouseWheelListener
This method:
Is fast to implement with very few lines of code.
Retains the benefits of the L&F.
Will remove both the buttons and the bar.
Below is a sample code for removing the verticall scroll bar.
JScrollPane myScrollPane = new JScrollPane();
//remove the scroll bar you don't want
myScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
JTextPane myJTextArea = new JTextPane();
//myScrollPane.setViewportView(myJTextArea);
myScrollPane.addMouseWheelListener(new MouseWheelListener() {
//this will mimick the behavior of scrolling
public void mouseWheelMoved(MouseWheelEvent e) {
JScrollBar scrollBar = myScrollPane.getVerticalScrollBar();
//capturing previous value
int previousValue = scrollBar.getValue();
int addAmount;
//decide where the wheel scrolled
//depending on how fast you want to scroll
//you can chane the addAmount to something greater or lesser
if(e.getWheelRotation()>0) {
addAmount = 2;
}else {
addAmount = -2;
}
//set the new value
scrollBar.setValue(previousValue + addAmount);
}
});