I've been told to use setters to change properties of a object and to have setters validate the data the property is being set to. I've also been told to not use setters in constructors due to subclass overriding. How should you go about validating the arguments of a constructor while allowing your setters to be overridden? Should you repeat the validation code?
With setters:
public class A {
private int x;
public A(int x){
setX(x);
}
public void setX(int x) {
if (x > 6)
this.x = x;
else
this.x = 7;
}
}
Without setters:
public class A {
private int x;
public A(int x){
this.x = x;
}
public void setX(int x) {
if (x > 6)
this.x = x;
else
this.x = 7;
}
}
Without setters and doubled code:
public class A {
private int x;
public A(int x){
if (x > 6)
this.x = x;
else
this.x = 7;
}
public void setX(int x) {
if (x > 6)
this.x = x;
else
this.x = 7;
}
}
One option is that you write a private method that is used in the setter and in the constructor so you haven't doubled code and the subclasses could overide the setter easily. This is my way of doing it.
If you aren't allowed to do that, you have to use doubled code.
---- EDIT: ----
This is only suitable for long checks or if no default value should be set.
public class A {
private int x;
public A(int x){
if(checkX())
this.x=x;
else
this.x = 7;
}
public void setX(int x) {
if (checkX(x))
this.x = x;
else
this.x = 7;
}
private boolean checkX(int x) {
if (x > 6)
return true;
else
retrun false;
}
}
Related
I've read some posts about function pointers but I still don't understand how to use 'function pointers' the best for my case. Also in this case It isn't clear to me the use of anonymous classes...
Here the code:
class Fitness {
private List < Double > list;
interface Foo {
//public Foo;
Object myFunc(Object arg);
Object myFunc2(Object arg);
}
public Fitness(List < Double > list) {
this.list = new ArrayList < Double > (list);
}
public void bar(Foo foo) {
Object object = foo.myFunc(list);
System.out.println(object);
Object object2 = foo.myFunc2(list);
System.out.println(object2);
}
public void method(String func) {
if (func.equals("f1"))
bar(
new Foo() {
public Object myFunc(Object arg) {
return (Double)((List) arg).get(0) + 50.0;
}
public Object myFunc2(Object arg) {
return (Double)((List) arg).get(0) + 50.0;
}
});
else if (func.equals("f2"))
bar(
new Foo() {
public Object myFunc(Object arg) {
List < Double > l = (List < Double > ) arg;
return l.get(0) / l.size();
}
public Object myFunc2(Object arg) {
List < Double > l = (List < Double > ) arg;
return l.get(0) / l.size();
}
});
}
public void fitness1() {
bar(
new Foo() {
public Object myFunc(Object arg) {
return (Double)((List) arg).get(0) + 50.0 * 1000;
}
public Object myFunc2(Object arg) {
return (Double)((List) arg).get(0) + 50.0;
}
});
}
}
class Example {
public static void main(String[] args) {
ArrayList < Double > listD = new ArrayList < Double > ();
listD.add(100.0);
listD.add(-1.0);
listD.add(-5.0);
Fitness t = new Fitness(listD);
//t.method("f1");
//t.method("f2");
//t.method2();
t.fitness1();
}
}
What I would like is an object Fitness that call a fitness function according to some parameters. A fitness method should be able to take a list of int, double, even couple <int, String>.
I want to do a test: so I want to see the different results if I choose f1, f2, f3, f4. I am confused about how to code it.
Thanks in advance
You can declare the following interface:
interface FooFunc {
Object invoke(Foo foo, Object arg);
}
Then change slightly your bar() method:
public void bar(Foo foo, FooFunc func) {
Object object = func.invoke(foo, list);
System.out.println(object);
}
... and your fitness1() method:
public void fitness1(FooFunc func) {
bar(
new Foo() {
public Object myFunc(Object arg) {
return (Double) ((List) arg).get(0) + 50.0 * 1000;
}
public Object myFunc2(Object arg) {
return (Double) ((List) arg).get(0) + 50.0;
}
}, func);
}
Now, from your main() method, you can do:
Fitness t = new Fitness(listD);
t.fitness1(Fitness.Foo::myFunc);
t.fitness1(Fitness.Foo::myFunc2);
Isn't it great?
UPDATE: Complete file
import java.util.ArrayList;
import java.util.List;
class Fitness {
private List<Double> list;
interface Foo {
//public Foo;
Object myFunc(Object arg);
Object myFunc2(Object arg);
}
interface FooFunc {
Object invoke(Foo foo, Object arg);
}
public Fitness(List<Double> list) {
this.list = new ArrayList<Double>(list);
}
public void bar(Foo foo, FooFunc func) {
Object object = func.invoke(foo, list);
System.out.println(object);
}
public void fitness1(FooFunc func) {
bar(
new Foo() {
public Object myFunc(Object arg) {
return (Double) ((List) arg).get(0) + 50.0 * 1000;
}
public Object myFunc2(Object arg) {
return (Double) ((List) arg).get(0) + 50.0;
}
}, func);
}
}
public class Example {
public static void main(String[] args) {
ArrayList<Double> listD = new ArrayList<>();
listD.add(100.0);
listD.add(-1.0);
listD.add(-5.0);
Fitness t = new Fitness(listD);
t.fitness1(Fitness.Foo::myFunc);
t.fitness1(Fitness.Foo::myFunc2);
}
}
I am working on libgdx.I am using this example https://github.com/oakes/libgdx-examples/tree/master/SuperKoalio/core/src/net/sekao/superkoalio to create a game.
I want to add controls on the screen, so that user can move left,right,up using the buttons.I used this "Controller" class https://github.com/BrentAureli/ControllerDemo/tree/master/core/src/com/brentaureli/overlaydemo
But I am not able to see any controls on the screen.Can any one please provide me solution to fix this.
public class MainScreen implements Screen {
Stage stage;
TiledMap map;
OrthogonalTiledMapRenderer renderer;
OrthographicCamera camera;
Koala koala;
Controller controller;
public void show() {
map = new TmxMapLoader().load("level1.tmx");
final float pixelsPerTile = 16;
renderer = new OrthogonalTiledMapRenderer(map, 1 / pixelsPerTile);
camera = new OrthographicCamera();
controller = new Controller();
stage = new Stage();
stage.getViewport().setCamera(camera);
koala = new Koala();
koala.layer = (TiledMapTileLayer) map.getLayers().get("walls");
koala.setPosition(20, 10);
stage.addActor(koala);
}
public void render(float delta) {
Gdx.gl.glClearColor(0.5f, 0.5f, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.position.x = koala.getX();
camera.update();
if(Gdx.app.getType() == Application.ApplicationType.Android)
controller.draw();
renderer.setView(camera);
renderer.render();
stage.act(delta);
stage.draw();
}
public void dispose() {
}
public void hide() {
}
public void pause() {
}
public void resize(int width, int height) {
camera.setToOrtho(false, 20 * width / height, 20);
controller.resize(width, height);
}
public void resume() {
}
}
Controller Class:
public class Controller {
Viewport viewport;
Stage stage;
boolean upPressed, downPressed, leftPressed, rightPressed;
OrthographicCamera cam;
public Controller(){
cam = new OrthographicCamera();
viewport = new FitViewport(800, 480, cam);
stage = new Stage(viewport);
stage.addListener(new InputListener(){
#Override
public boolean keyDown(InputEvent event, int keycode) {
switch(keycode){
case Input.Keys.UP:
upPressed = true;
break;
case Input.Keys.DOWN:
downPressed = true;
break;
case Input.Keys.LEFT:
leftPressed = true;
break;
case Input.Keys.RIGHT:
rightPressed = true;
break;
}
return true;
}
#Override
public boolean keyUp(InputEvent event, int keycode) {
switch(keycode){
case Input.Keys.UP:
upPressed = false;
break;
case Input.Keys.DOWN:
downPressed = false;
break;
case Input.Keys.LEFT:
leftPressed = false;
break;
case Input.Keys.RIGHT:
rightPressed = false;
break;
}
return true;
}
});
Gdx.input.setInputProcessor(stage);
Table table = new Table();
table.left().bottom();
Image upImg = new Image(new Texture("flatDark25.png"));
upImg.setSize(50, 50);
upImg.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
upPressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
upPressed = false;
}
});
Image downImg = new Image(new Texture("flatDark26.png"));
downImg.setSize(50, 50);
downImg.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
downPressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
downPressed = false;
}
});
Image rightImg = new Image(new Texture("flatDark24.png"));
rightImg.setSize(50, 50);
rightImg.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
rightPressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
rightPressed = false;
}
});
Image leftImg = new Image(new Texture("flatDark23.png"));
leftImg.setSize(50, 50);
leftImg.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
leftPressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
leftPressed = false;
}
});
table.add();
table.add(upImg).size(upImg.getWidth(), upImg.getHeight());
table.add();
table.row().pad(5, 5, 5, 5);
table.add(leftImg).size(leftImg.getWidth(), leftImg.getHeight());
table.add();
table.add(rightImg).size(rightImg.getWidth(), rightImg.getHeight());
table.row().padBottom(5);
table.add();
table.add(downImg).size(downImg.getWidth(), downImg.getHeight());
table.add();
stage.addActor(table);
}
public void draw(){
stage.draw();
}
public boolean isUpPressed() {
return upPressed;
}
public boolean isDownPressed() {
return downPressed;
}
public boolean isLeftPressed() {
return leftPressed;
}
public boolean isRightPressed() {
return rightPressed;
}
public void resize(int width, int height){
viewport.update(width, height);
}
}
class ballbouncepanel extends JPanel
{
public void start()
{
Timer timer;
final int FREQ = 45;
timer = new Timer(FREQ, new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
repaint();
}
});
timer.start();
}
Rect rect = new Rect();
public Dimension getPreferredSize()
{
return new Dimension(250,200);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
rect.draw(g);
rect.move(g);
rect.erase(g);
}
}
class Rect
{
public int xLocation = 0;
public int yLocation = 0;
public int xVelocity = 10;
public int yVelocity = 10;
public void draw(Graphics g)
{
g.setColor(Color.cyan);
g.fillRect(xLocation, yLocation, 20, 20);
}
public void move(Graphics g)
{
xLocation += xVelocity;
yLocation += yVelocity;
}
public void erase(Graphics g)
{
g.setColor(Color.white);
g.fillRect(xLocation, yLocation, 20, 20);
}
}
The new error is that now my repaint method isn't working.
Above is my code for the frame that I got that I want to paint on, I understand paint using a applet or JApplet, but I am trying to do what I did in a applet on Swing, and now im running into problems, I have looked up many tutorials on how to implement graphics in, but most of them is just running a main graphics, I need mine to be in this specific frame(BB). If anyone could help me understand or point me to a beginners tutorial for it, it would be appreciated.
I think you are just forgetting to call the start() method of your ballbouncepanel. Also a note: you're move() method does no painting, so take out the Graphics argument and just call it in the timer
Also not sure what the erase method is supposed to do, but I'm thinking you want to change color every tick of the timer. In that case, just keep a color variable, and just change that variable. You can see the example below
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class bounceballpanel extends JPanel {
public void start() {
Timer timer;
final int FREQ = 45;
timer = new Timer(FREQ, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
rect.move();
rect.changeColor();
repaint();
}
});
timer.start();
}
Rect rect = new Rect();
public Dimension getPreferredSize() {
return new Dimension(250, 200);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
rect.draw(g);
//rect.erase(g);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
JFrame frame = new JFrame();
bounceballpanel panel = new bounceballpanel();
panel.start();
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
class Rect {
public int xLocation = 0;
public int yLocation = 0;
public int xVelocity = 10;
public int yVelocity = 10;
Color color = Color.cyan;
public void draw(Graphics g) {
g.setColor(color);
g.fillRect(xLocation, yLocation, 20, 20);
}
public void move() {
xLocation += xVelocity;
yLocation += yVelocity;
}
public void changeColor() {
if (color == Color.cyan) {
color = Color.white;
} else {
color = Color.cyan;
}
}
/*
public void erase(Graphics g) {
g.setColor(Color.white);
g.fillRect(xLocation, yLocation, 20, 20);
}*/
}
I've looked at other Stackoverflow questions and done what the answers have told me, but I can't seem to get my class to display any text.
Here's my code where all the text is being displayed:
package com.frinkly.jumpcat;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.OrthographicCamera;
public class WorldRenderer {
private static final float CAMERA_WIDTH = 12f;
private static final float CAMERA_HEIGHT = 20f;
private OrthographicCamera cam;
private SpriteBatch spriteBatch;
private int width;
private int height;
private float ppuX;
private float ppuY;
private BitmapFont font;
private World world;
private Cat cat;
ShapeRenderer debugRenderer = new ShapeRenderer();
public WorldRenderer(World newWorld) {
this.world = newWorld;
this.cat = world.getCat();
this.cam = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
this.cam.position.set(CAMERA_WIDTH / 2f, CAMERA_HEIGHT / 2f, 0);
spriteBatch = new SpriteBatch();
font = new BitmapFont(Gdx.files.internal("font/font.fnt"), false);
font.setColor(Color.BLACK);
this.cam.update();
spriteBatch.setProjectionMatrix(new Matrix4().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()));
}
public void setSize(int newWidth, int newHeight) {
width = newWidth;
height = newHeight;
ppuX = (float) width / CAMERA_WIDTH;
ppuY = (float) height / CAMERA_HEIGHT;
}
public void render() {
cam.update();
spriteBatch.begin();
debugDraw();
drawPoints();
spriteBatch.end();
}
private void drawPoints() {
font.setColor(1.0f, 1.0f, 1.0f, 1.0f);
font.setScale(1, height/width);
font.draw(spriteBatch, Integer.toString(cat.getPoints()), 0.5f, height/width*0.5f);
}
private void debugDraw() {
debugRenderer.setProjectionMatrix(cam.combined);
debugRenderer.begin(ShapeType.Filled);
for(Block block : world.getBlocks()) {
Rectangle rect1 = block.getBounds1();
Rectangle rect2 = block.getBounds2();
float x1 = block.getPosition().x;//+block.getPosition().x
float y1 = block.getPosition().y;//+block.getPosition().y
debugRenderer.setColor(new Color(1, 0, 0, 1));
debugRenderer.rect(x1, y1, rect1.width, rect1.height);
debugRenderer.rect(x1, y1 + rect1.height + block.getSPACE(), rect2.width, rect2.height);
}
Rectangle rect = cat.getBounds();
float x1 = cat.getPosition().x + rect.x;
float y1 = cat.getPosition().y + rect.y;
debugRenderer.setColor(new Color(0, 1, 0, 1));
debugRenderer.rect(x1, y1, rect.width, rect.height);
debugRenderer.end();
}
private void drawBlocks() {
}
private void drawCat() {
}
}
Here's the GameScreen that calls the renderer to display the text:
package com.frinkly.jumpcat;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.Screen;
public class GameScreen implements Screen, InputProcessor{
private World world;
private WorldRenderer renderer;
private CatController catController;
private BlockController blockController;
private int screenWidth;
private int screenHeight;
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1f, 1f, 1f, 1f);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
blockController.update(delta);
catController.update(delta);
renderer.render();
}
#Override
public void resize(int width, int height) {
screenWidth = width;
screenHeight = height;
renderer.setSize(width, height);
}
#Override
public void show() {
loadAssets();
world = new World();
renderer = new WorldRenderer(world);
catController = new CatController(world);
blockController = new BlockController(world);
blockController.start();
Gdx.input.setInputProcessor(this);
}
private void loadAssets() {
}
#Override
public void hide() {
Gdx.input.setInputProcessor(null);
}
#Override
public void pause() {
Gdx.input.setInputProcessor(null);
}
#Override
public void resume() {
Gdx.input.setInputProcessor(this);
}
#Override
public void dispose() {
}
#Override
public boolean keyDown(int keycode) {
if(keycode == Keys.SPACE) {
catController.jumpPressed();
}
return true;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
if(!Gdx.app.getType().equals(ApplicationType.Android)) {
return false;
}
catController.jumpPressed();
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
if(!Gdx.app.getType().equals(ApplicationType.Android)) {
return false;
}
return true;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean scrolled(int amount) {
// TODO Auto-generated method stub
return false;
}
}
My fonts are in the right folder, and I used Hiero to generate the files. I used 150 size and it generated font1png-font5.png, which I've also put in my font folder.
The error should be in your render() method:
cam.update();
spriteBatch.begin();
debugDraw();
drawPoints();
spriteBatch.end();
Inside debugDraw() you begin() a ShapeRenderer. So 2 objects try to draw at the same time. Do the debugDraw() first and begin() your SpriteBatch after that:
cam.update();
debugDraw();
spriteBatch.begin();
drawPoints();
spriteBatch.end();
Hope it helps
I'm struggling with a at the first sight simple problem (and probably it is so...) - I have to disable certain button in the JTable upon value in one of the cells within the same row.
Below is my inner class for button rendering and editing:
private class CellButton {
class ButtonsPanel extends JPanel {
public JButton jbutton = new JButton("Accept!!");
public ButtonsPanel() {
super();
setOpaque(true);
jbutton.setFocusable(false);
jbutton.setRolloverEnabled(false);
jbutton.setSize(122, 30);
jbutton.setFont(new java.awt.Font("Tahoma", 3, 12));
jbutton.setForeground(new java.awt.Color(0, 102, 102));
add(jbutton);
}
private class ButtonsRenderer extends ButtonsPanel implements TableCellRenderer {
ButtonsPanel bp;
public ButtonsRenderer() {
super();
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
this.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
Object o = table.getModel().getValueAt(row, 8);
bp = (ButtonsPanel) o;
if (jTable5.getValueAt(row, 3).equals("NORMALNA")) {
bp.jbutton.setEnabled(false);
}
return this;
}
}
private class ButtonsEditor extends ButtonsPanel implements TableCellEditor {
ButtonsPanel bp;
public ButtonsEditor(final JTable table, final String tableName) {
super();
//DEBUG: view button click -> control key down + edit button(same cell) press -> remain selection color
MouseListener ml = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
ButtonModel m = ((JButton) e.getSource()).getModel();
if (m.isPressed() && table.isRowSelected(table.getEditingRow()) && e.isControlDown()) {
setBackground(table.getBackground());
}
}
};
jbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int row = table.convertRowIndexToModel(table.getEditingRow());
Object o = table.getModel().getValueAt(row, 0);
fireEditingStopped();
//update info status
setDmlUpdateStatusPrejeteInfo();
jDialog2.requestFocus();
}
});
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
fireEditingStopped();
}
});
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
this.setBackground(table.getSelectionBackground());
Object o = table.getModel().getValueAt(row, 8);
bp = (ButtonsPanel) o;
if (jTable5.getValueAt(row, 3).equals("NORMALNA")) {
bp.jbutton.setEnabled(false);
}
return this;
}
#Override
public Object getCellEditorValue() {
return "";
}
transient protected ChangeEvent changeEvent = null;
#Override
public boolean isCellEditable(EventObject e) {
return true;
}
#Override
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
#Override
public boolean stopCellEditing() {
fireEditingStopped();
return true;
}
#Override
public void cancelCellEditing() {
fireEditingCanceled();
}
#Override
public void addCellEditorListener(CellEditorListener l) {
listenerList.add(CellEditorListener.class, l);
}
#Override
public void removeCellEditorListener(CellEditorListener l) {
listenerList.remove(CellEditorListener.class, l);
}
public CellEditorListener[] getCellEditorListeners() {
return listenerList.getListeners(CellEditorListener.class);
}
protected void fireEditingStopped() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == CellEditorListener.class) {
// Lazily create the event:
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((CellEditorListener) listeners[i + 1]).editingStopped(changeEvent);
}
}
}
protected void fireEditingCanceled() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == CellEditorListener.class) {
// Lazily create the event:
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((CellEditorListener) listeners[i + 1]).editingCanceled(changeEvent);
}
}
}
}
public ButtonsRenderer br() {
return new ButtonsRenderer();
}
public ButtonsEditor be(JTable jTable, String tableName) {
return new ButtonsEditor(jTable, tableName);
}
}
a) it's better not to call a Jbutton in the name Jbutton, it's just confusing
b) there are many way to disable a jbutton (make it disappear, remove it, resize it...) but the best one is probably this:
Jbutton.setEnabled(false);
c) I think you can use this very useful guide: http://www.macs.hw.ac.uk/guidebook/?name=JButton&page=1