Code
public class MainPanel extends JPanel {
private static final Color evenColor = new Color(240, 255, 250);
private static final LinkViewRadioButtonUI ui = new LinkViewRadioButtonUI();
private static int LR_PAGE_SIZE = 5;
private final TestModel model = new TestModel();
private final TableRowSorter< TestModel > sorter = new TableRowSorter< TestModel >(model);
private final Box box = Box.createHorizontalBox();
public MainPanel() {
super(new BorderLayout());
JTable table = new JTable(model) {
@Override
public Component prepareRenderer(TableCellRenderer tcr, int row, int column) {
Component c = super.prepareRenderer(tcr, row, column);
if(isRowSelected(row)) {
c.setForeground(getSelectionForeground());
c.setBackground(getSelectionBackground());
}else{
c.setForeground(getForeground());
c.setBackground((row%2==0)?evenColor:getBackground());
}
return c;
}
};
table.setFillsViewportHeight(true);
table.setIntercellSpacing(new Dimension());
table.setShowHorizontalLines(false);
table.setShowVerticalLines(false);
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
table.setRowSorter(sorter);
for(int i=0;i <= 2008;i++) {
model.addTest(new Test(" Test: "+i, (i%2==0)?"":"comment..."));
}
initLinkBox(100, 1);
add(box, BorderLayout.NORTH);
add(new JScrollPane(table));
setPreferredSize(new Dimension(320, 240));
}
private void initLinkBox(final int itemsPerPage, final int currentPageIndex) {
//assert currentPageIndex > 0;
sorter.setRowFilter(makeRowFilter(itemsPerPage, currentPageIndex-1));
ArrayList< JRadioButton > l = new ArrayList< JRadioButton >();
int startPageIndex = currentPageIndex-LR_PAGE_SIZE;
if(startPageIndex <= 0) startPageIndex = 1;
//#if 0
//int maxPageIndex = (model.getRowCount()/itemsPerPage)+1;
//#else
/* "maxPageIndex" gives one blank page if the module of the division is not zero.
* pointed out by erServi
* e.g. rowCount=100, maxPageIndex=100
*/
int rowCount = model.getRowCount();
int maxPageIndex = (rowCount/itemsPerPage) + (rowCount%itemsPerPage==0?0:1);
//#endif
int endPageIndex = currentPageIndex+LR_PAGE_SIZE-1;
if(endPageIndex>maxPageIndex) endPageIndex = maxPageIndex;
if(currentPageIndex > 1)
l.add(makePNRadioButton(itemsPerPage, currentPageIndex-1, "Prev"));
//for(int i=startPageIndex;i <= endPageIndex;i++)
// l.add(makeRadioButton(itemsPerPage, currentPageIndex, i-1));
//if I only have one page, Y don't want to see pagination buttons
//suggested by erServi
if(startPageIndex < endPageIndex) {
for(int i=startPageIndex; i<= endPageIndex;i++) {
l.add(makeRadioButton(itemsPerPage, currentPageIndex, i-1));
}
}
if(currentPageIndex < maxPageIndex)
l.add(makePNRadioButton(itemsPerPage, currentPageIndex+1, "Next"));
box.removeAll();
ButtonGroup bg = new ButtonGroup();
box.add(Box.createHorizontalGlue());
for(JRadioButton r:l) {
box.add(r); bg.add(r);
}
box.add(Box.createHorizontalGlue());
box.revalidate();
box.repaint();
l.clear();
}
private JRadioButton makeRadioButton(final int itemsPerPage,
final int current, final int target) {
JRadioButton radio = new JRadioButton(""+(target+1));
radio.setForeground(Color.BLUE);
radio.setUI(ui);
if(target+1==current) {
radio.setSelected(true);
radio.setForeground(Color.BLACK);
}
radio.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
initLinkBox(itemsPerPage, target+1);
}
});
return radio;
}
private JRadioButton makePNRadioButton(final int itemsPerPage, final int target, String title) {
JRadioButton radio = new JRadioButton(title);
radio.setForeground(Color.BLUE);
radio.setUI(ui);
radio.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
initLinkBox(itemsPerPage, target);
}
});
return radio;
}
private RowFilter< TestModel, Integer > makeRowFilter(final int itemsPerPage, final int target) {
return new RowFilter< TestModel, Integer >() {
@Override
public boolean include(Entry< ? extends TestModel, ? extends Integer > entry) {
int ei = entry.getIdentifier();
return (target*itemsPerPage <= ei && ei < target*itemsPerPage+itemsPerPage);
}
};
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
try{
UIManager.getInstalledLookAndFeels();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(Exception e) {
e.printStackTrace();
}
final JFrame frame = new JFrame("@title@");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new MainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
References
Hi Atsuhiro,
ReplyDeleteVery nice Work, thanks a lot.
But i recognised an extreme CPU-usage when using your class on my system.
There seems to be a circuit, which can be prevented by changing 3 lines of code in your paint-Method:
- b.setForeground(Color.BLUE);
- b.setForeground(Color.BLACK);
+ if (b.getForeground()!=Color.BLACK) b.setForeground(Color.BLACK);
and the same for the gray color.
Maybe not elegant but it helped
Thanks again,
Peter
Thanks for your help!
ReplyDeleteThis is clearly an infinite repaint loop bug.
89c89,92
< if(target+1==current) radio.setSelected(true);
---
> if(target+1==current) {
> radio.setSelected(true);
> radio.setForeground(Color.BLACK);
> }
195c198
< b.setForeground(Color.BLUE);
---
> //b.setForeground(Color.BLUE);
197c200
< b.setForeground(Color.GRAY);
---
> //b.setForeground(Color.GRAY);
199c202
< b.setForeground(Color.BLACK);
---
> //b.setForeground(Color.BLACK);
Thanks again for the correction.
This comment has been removed by the author.
ReplyDeleteLinkViewRadioButtonUI is giving compilation error pls help
ReplyDeleteparamupk@gmail.com
Hi, ranjeeth.
ReplyDeleteHmm, what OS and Java version are you using?
(Works fine for me on Windows XP using Java 1.6.0_22)
Hi,
ReplyDeleteNice One.... and thanks for Ur work great
Can anyone explain the code. like Role of table model, Underline in radio-button and working flow
In my case i will be getting an array-list of bean(i.e setters)
So i need to iterate and copy to object[][].So if huge number of record is coming it will be a performance issue ???
And i need to apply pagination so were i have to change ??
Plz do help
I'm not sure of the problem, but how about to use a DefaultTableModel#addRow(Object[]) instead of "copy to object[][]".
ReplyDeleteBTW, what has become of LinkViewRadioButtonUI compilation error?
I solved Everything.....
ReplyDeleteBut have a problem
When user click on the header whole model should get sorted not the view??
What to do ??
For Example u have data from A - Z your current view contains a-c so sorting will become c -a but i need Z to come first....
One way is to do something like this: TablePaginationTest.java
ReplyDelete(But this looks like ugly hack!)
Very good code, thanks!
ReplyDeleteBTW, there is one or two little improvements:
1. "maxPageIndex" gives one blank page if the module of the division is not zero.
So:
int maxPageIndex = (getTableModel(false).getRowCount() % itemsPerPage) == 0 ? (getTableModel(false).getRowCount() / itemsPerPage) : ((getTableModel(false).getRowCount() / itemsPerPage) + 1);
2. Also, if I only have one page, Y don't want to see pagination buttons, so:
if(startPageIndex < endPageIndex)
for(int i = startPageIndex; i <= endPageIndex; i ++) paginationButtons.add(makeRadioButton(itemsPerPage, currentPageIndex, i - 1));
Thank you again!
Perfect! Thanks for the corrections, erServi.
ReplyDeleteHi,
ReplyDeleteI am newbie in Swing, I like this pagination in JTable, my question please how to use it with from a resultset from a jdbc connection from a database or using hibernate ?
thanks, your help is appreciated.
Hi, Majid.
ReplyDeleteLoading all data at once, or step by step, at any rate, you might be able to use a SwingWorker: TablePaginationLoadingTest.java
private int currentPageIndex = 1;
static class MyBean{
private String name;
private int age;
public MyBean() {
name = "empty";
age = -1;
}
public MyBean(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
private final JButton button = new JButton(new AbstractAction("get") {
@Override public void actionPerformed(ActionEvent e) {
table.setEnabled(false);
button.setEnabled(false);
SwingWorker> worker = new SwingWorker>() {
private int itemsPerPage = 100;
private int max = 3000;
@Override public String doInBackground() {
int current = 0;
// Hibernate: not tested
// SessionFactory factory = new Configuration().configure().buildSessionFactory();
// Session session = factory.openSession();
// Criteria criteria = session.createCriteria(MyBean.class);
// criteria.setMaxResults(itemsPerPage);
while(current result = criteria.list();
// make dummy list
Thread.sleep(2000);
java.util.List result = new java.util.ArrayList(itemsPerPage);
for(int i=0;i> chunks) {
for(java.util.List list : chunks) {
for(MyBean mb: list) {
model.addRow(new Object[] {mb.getName(), mb.getAge()});
}
}
initLinkBox(itemsPerPage, currentPageIndex);
}
@Override public void done() {
String text = null;
if(isCancelled()) {
text = "Cancelled";
}else{
try {
text = get();
}catch(Exception ex) {
ex.printStackTrace();
text = "Exception";
}
}
table.setEnabled(true);
button.setEnabled(true);
}
};
worker.execute();
}
});
//......
Hi..
ReplyDeleteI am just learning swing and I like the pagination you created in table.Instead of using too much number of toggle buttons ,I need only 4 toggle buttons i.e. First Prev Next Last.Can you tell me how to do that in your code?.My emailid - vishalkadu87@gmail.com
Hi, Vishal.
ReplyDeleteIt's kind of hard to explain in English for me, so check out this example: https://gist.github.com/aterai/7261520
Really Great..
ReplyDeleteThis is what I wanted.. Thanks.
Just only thing need to add is Page No ,Total pages and search according to page no(Example :: Page 1 out of 10 and when we type page no in Text Field it will redirect on that page).
Hi, Vishal.
ReplyDeleteI’ve updated the gist code :)
Nice work.
ReplyDeleteThank you again.It helps me a lot
Hi, Atsuhiro
ReplyDeleteThanks for guiding me.Now I am facing critical problem in JTable and need your help.
Problem::If there are 50,000 or more rows in the table then it takes too much time to load.So how can I solve this problem and how can I show instant data in table with the same code on github.
Hi, Vishal
ReplyDeleteHow about using the SwingWorker http://java-swing-tips.googlecode.com/svn/trunk/PageInputForPagination/src/java/example/MainPanel.java