1

I can't find a way (is there any ?) to format the style of tabs titles in a JTabbedPane.

I can change the background color of the tab panes (see below), but can't find a way to style the titles of the tabs; I would like to have them bold or red or be able to define the tabs width, for instance, like I could format the style of the labels in the first panel.

Here's the code, mostly inspired by tim_yates (Groovy SwingBuilder : using a scrollpanel to show a list of panels) :

import groovy.swing.SwingBuilder
import javax.swing.WindowConstants as WC
import javax.swing.JOptionPane
import javax.swing.JTabbedPane
import javax.swing.JScrollPane
import javax.swing.BoxLayout as BXL
import java.awt.Font

Font font = new Font("Serif", Font.BOLD, 13) 
int numPanels = 20

swing = new SwingBuilder()
frame = swing.frame(title:'test', pack:true,   visible:true, defaultCloseOperation:WC.DISPOSE_ON_CLOSE) {
    tabbedPane(id: 'tabs', tabLayoutPolicy:JTabbedPane.SCROLL_TAB_LAYOUT) {
        panel(name: 'Tab 1', background:java.awt.Color.WHITE ) {
            boxLayout(axis: BXL.Y_AXIS) 
            panel(alignmentX: 0f, background:java.awt.Color.WHITE){
                label ( 'Label 1', preferredSize: [104, 24]).setFont(font) 
                label ( 'Label 2', preferredSize: [104, 24]).setFont(font) 
                label ( 'Label 3', preferredSize: [104, 24]).setFont(font) 
            }   
            scrollPane( verticalScrollBarPolicy:JScrollPane.VERTICAL_SCROLLBAR_ALWAYS) {
                vbox (){
                    (1..numPanels).each { num ->
                        def panelID = "panel$num"
                        def pane = panel( alignmentX:0f, id:panelID, background:java.awt.Color.GREEN ) {
                            label('description') 
                            textField( id: "description$num", text:panelID, columns: 70 )
                            button( id: "buttonpanel$num", text:panelID, actionPerformed:{
                            swing."$panelID".background = java.awt.Color.RED
                            } )
                        }
                    }
                }
            }
        }       
        panel(name: 'Tab 2', background:java.awt.Color.WHITE) {
            textField(text: 'Some text', columns: 15)
            scrollPane() {
                textArea(text: 'Some text', columns: 15, rows: 4)
            }
        }       
    }
    boxLayout(axis: BXL.Y_AXIS)
    panel(id:'secondPanel', background:java.awt.Color.WHITE){                       
        button('Quit', actionPerformed:{
        dispose()
        })
    }   
}
frame.size = [ frame.width, 600 ]

I found these links which look very difficult (to me) to implement in Groovy :

Also the Java docs do not explain how to do that, and I didn't find any example using styled tabs.

Thanks for your help.

Regards,

Michel.

PS : Ant's offered a link

Groovy SwingBuilder : changing size and/or font of tabs (in jTabbedpane)

to an interesting article, but not directly helpful for my question (initially too vague).

Community
  • 1
  • 1

1 Answers1

3

I believe you need to call jtabbedpane.setTabComponentAt (the javadoc for which can be found here)

This requires you be using Java 6 (for Java 5, you are going to have to look into writing a custom TabbedPaneUI class, and overriding this -- or use a custom JTabbedPane class from some other source that allows this)

Here's an example of it in action:

import groovy.swing.SwingBuilder
import javax.swing.WindowConstants as WC
import javax.swing.JOptionPane
import javax.swing.JTabbedPane
import javax.swing.JScrollPane
import javax.swing.BoxLayout as BXL
import java.awt.Font

Font font = new Font("Serif", Font.BOLD, 13) 
int numPanels = 20

swing = new SwingBuilder()

frame = swing.frame(title:'test', pack:true,   visible:true, defaultCloseOperation:WC.DISPOSE_ON_CLOSE) {
    vbox {
        tabbedPane(id: 'tabs', tabLayoutPolicy:JTabbedPane.SCROLL_TAB_LAYOUT) {
            panel( name:'Tab 1', background:java.awt.Color.WHITE ) {
                vbox {
                    panel( background:java.awt.Color.WHITE ){
                        label ( 'Label 1', preferredSize: [104, 24]).setFont(font) 
                        label ( 'Label 2', preferredSize: [104, 24]).setFont(font) 
                        label ( 'Label 3', preferredSize: [104, 24]).setFont(font) 
                    }   
                    scrollPane( verticalScrollBarPolicy:JScrollPane.VERTICAL_SCROLLBAR_ALWAYS) {
                        vbox {
                            (1..numPanels).each { num ->
                                def panelID = "panel$num"
                                def pane = panel( alignmentX:0f, id:panelID, background:java.awt.Color.GREEN ) {
                                    label('description') 
                                    textField( id: "description$num", text:panelID, columns: 70 )
                                    button( id: "buttonpanel$num", text:panelID, actionPerformed:{
                                        swing."$panelID".background = java.awt.Color.RED
                                    } )
                                }
                            }
                        }
                    }
                }
            }       
            panel(name: 'Tab 2', background:java.awt.Color.WHITE) {
                textField(text: 'Some text', columns: 15)
                scrollPane() {
                    textArea(text: 'Some text', columns: 15, rows: 4)
                }
            }       
        }
        panel(id:'secondPanel', background:java.awt.Color.WHITE){                       
            button('Quit', actionPerformed:{
                dispose()
            })
        }   
    }
}

// Define a list of labels for our tabs
def tabComponents = [
  swing.label( text:'Tab 1', font:font.deriveFont( Font.ITALIC ) ),
  swing.label( text:'Tab 2', font:font.deriveFont( 20.0f ) )
]
// Set the tab componets to our labels
tabComponents.eachWithIndex { lbl, idx ->
  swing.tabs.setTabComponentAt idx, lbl
}

frame.size = [ frame.width, 600 ]

PS: You might want to remove your other question that I just found... Generally editing a question to include extra informations is better than posting a new question asking the same thing but with more information

Community
  • 1
  • 1
tim_yates
  • 167,322
  • 27
  • 342
  • 338
  • tyvm, tim ! just what I was looking for. – Michel Parmentier Jun 27 '11 at 10:57
  • In the meantime I had tried this solution : tabbedPane() { }.setFont(font) which works properly for setting font style, but could not extend it to customize width or colors – Michel Parmentier Jun 27 '11 at 11:02
  • whereas your solution allows more flexibility : def tabComponents = [ swing.label( text:'Tab 1', font:font.deriveFont( Font.ITALIC ), foreground:java.awt.Color.RED, preferredSize: [104, 24] ), swing.label( text:'Tab 2', font:font.deriveFont( 20.0f ) ) ] – Michel Parmentier Jun 27 '11 at 11:05
  • concerning your PS, I can't find an option to delete the first post. I think I chose to create a new post because of difficulties to edit the first one. – Michel Parmentier Jun 27 '11 at 12:00
  • @Michel Ahhh, fair enough :-) Good to remember for next time :-) – tim_yates Jun 27 '11 at 12:03
  • well, it seems there is an easy and elegant solution : tabs.setForeground(colorRed) tabs.setFont(font) ; however I didn't find a way to extend to other formatting properties , like size, width, adding an icon, etc ; any ideas ? – Michel Parmentier Jun 29 '11 at 11:00
  • Tim, not being a programmer, I'm able to adapt a script (duh, by trial and many errors), but I don't really understand the gist of it; so, I'm must admit I don't get your question; the 2 lines of code answer my immediate needs, but I guess "using a component" (that is, the lines of code you added at the end) will allow me more flexibility if I have many tabs that I want to customize, is that right ? – Michel Parmentier Jun 29 '11 at 13:04