package com.pugh.sockso.gui;
import com.pugh.sockso.Properties;
import com.pugh.sockso.Utils;
import com.pugh.sockso.db.Database;
import com.pugh.sockso.gui.controls.BooleanOptionField;
import com.pugh.sockso.resources.Resources;
import com.pugh.sockso.web.User;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.pugh.sockso.Constants;
import javax.swing.JOptionPane;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import org.apache.log4j.Logger;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
@Singleton
public class UsersPanel extends JPanel implements TableModelListener {
private static Logger log = Logger.getLogger( UsersPanel.class );
private final Injector injector;
private final Properties p;
private final Database db;
private final Resources r;
private final JFrame parent;
private MyTableModel model;
private JTable table;
private boolean isRefreshing;
@Inject
public UsersPanel( final Injector injector, final AppFrame parent, final Database db,
final Properties p, final Resources r ) {
this.injector = injector;
this.parent = parent;
this.db = db;
this.p = p;
this.r = r;
isRefreshing = false;
}
/**
* Initialise the users panel
*
*/
public void init() {
setLayout( new BorderLayout() );
add( getOptionsPane(), BorderLayout.NORTH );
add( getAccountsPane(), BorderLayout.CENTER );
model.addTableModelListener( this );
startAutoRefresh();
}
/**
* Start the thread to auto-refresh the table data as long as the user
* isn't editing the table
*
*/
protected void startAutoRefresh() {
final long refreshTimeout = 1000 * 30;
new Thread() {
@Override
public void run() {
while ( true ) {
try {
if ( !table.isEditing() ) {
refreshUsers();
}
sleep( refreshTimeout );
}
catch ( final InterruptedException e ) {}
}
}
}.start();
}
/**
* returns the options pane at the top of the panel
*
* @return panel with options on
*
*/
private JPanel getOptionsPane() {
FormLayout layout = new FormLayout(
" right:max(60dlu;pref), 10dlu, 150dlu, 7dlu "
);
DefaultFormBuilder builder = new DefaultFormBuilder(layout);
builder.setDefaultDialogBorder();
builder.appendSeparator( "Options" );
builder.append( "Require login:", new BooleanOptionField(p,Constants.WWW_USERS_REQUIRE_LOGIN) );
builder.nextLine();
builder.append( "Disable registering:", new BooleanOptionField(p,Constants.WWW_USERS_DISABLE_REGISTRATION) );
builder.nextLine();
builder.append( "Require activation:", new BooleanOptionField(p,Constants.WWW_USERS_REQUIRE_ACTIVATION) );
builder.nextLine();
return builder.getPanel();
}
/**
* the main pane with the user accounts controls
*
*/
private JPanel getAccountsPane() {
JButton delete = new JButton( "Delete", new ImageIcon(r.getImage("icons/16x16/delete.png")) );
delete.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent evt ) {
deleteSelectedUser();
}
});
JButton create = new JButton( "Create User", new ImageIcon(r.getImage("icons/16x16/add.png")) );
create.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent evt ) {
injector.getInstance( CreateUserDialog.class );
}
});
JPanel accBtns = new JPanel( new FlowLayout(FlowLayout.LEFT) );
accBtns.add( create );
accBtns.add( delete );
// create users table
model = new MyTableModel();
table = new JTable( model );
TableColumnModel columns = table.getColumnModel();
table.getSelectionModel().setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
// set table column widths
int[] widths = { 10, 150, 200, 90, 10, 10 };
for ( int i=0; i<widths.length; i++ )
columns.getColumn(i).setPreferredWidth( widths[i] );
JPanel pn = new JPanel();
pn.setLayout( new BorderLayout() );
pn.add( new JScrollPane(table), BorderLayout.CENTER );
pn.add( accBtns, BorderLayout.SOUTH );
return pn;
}
/**
* Save the users changes when the table is changed
*
* @param evt
*
*/
public void tableChanged( final TableModelEvent evt ) {
if ( !isRefreshing ) {
saveChanges();
}
}
/**
* Saves any changes made to the users data table
*
*/
protected void saveChanges() {
for ( int i=0; i<table.getRowCount(); i++ ) {
User user = new User(
Integer.parseInt( model.getValueAt(i,0).toString() ),
(String) model.getValueAt( i, 1 ),
(String) model.getValueAt( i, 2 ),
model.getValueAt( i, 4 ).equals( "true")
);
user.setActive( model.getValueAt( i, 5 ).equals("1") );
try { user.update(db); }
catch ( final SQLException e ) {
log.error( e.getMessage() );
JOptionPane.showMessageDialog(
parent,
e.getMessage(),
"Sockso",
JOptionPane.ERROR_MESSAGE
);
}
}
}
/**
* if there is a user selected in the table, tries to
* delete it
*
*/
protected void deleteSelectedUser() {
int row = table.getSelectedRow();
if ( row != -1 ) {
try {
int id = Integer.parseInt( (String) model.getValueAt(row,0) );
User.delete( db, id );
refreshUsers();
}
catch ( SQLException e ) {
log.error( e );
}
}
}
/**
* loads users from the database to the users table
*
*/
protected void refreshUsers() {
isRefreshing = true;
for ( int i=model.getRowCount(); i>0; i-- )
model.removeRow( i - 1 );
PreparedStatement st = null;
ResultSet rs = null;
try {
final String sql = " select u.id, u.name, u.email, u.date_created, u.is_admin, u.is_active " +
" from users u " +
" order by u.name asc ";
st = db.prepare( sql );
rs = st.executeQuery();
while ( rs.next() ) {
int row = model.getRowCount() + 1;
model.setRowCount( row );
model.setValueAt( rs.getString("id"), row - 1, 0 );
model.setValueAt( rs.getString("name"), row - 1, 1 );
model.setValueAt( rs.getString("email"), row - 1, 2 );
model.setValueAt( rs.getString("date_created"), row - 1, 3 );
model.setValueAt( rs.getString("is_admin"), row - 1, 4 );
model.setValueAt( rs.getString("is_active"), row - 1, 5 );
}
}
catch ( SQLException e ) {
log.error( e );
}
finally {
Utils.close( rs );
Utils.close( st );
isRefreshing = false;
}
}
}
class MyTableModel extends DefaultTableModel {
private String[] columns = { "ID", "Name", "Email", "Date Created", "Admin", "Active" };
@Override
public int getColumnCount() { return columns.length; }
@Override
public String getColumnName( int i ) { return columns[i]; }
}