In the below image I am trying to achieve the following.I have a table and lots of labels embossed over table cells.The height of the labels is always equal to the cell height.So if two labels come in the same point one hides the another as shown in the longer rectangles with red rect over blue.Alternatively what I want is to make the height as half and there by show both the rectangles(showing starting and end points of the rectangle since height is of no use I can half the height of the rectangle to accomodate one more in the same cell.)
I have to do this inside a JTable.To attach a label we can create a JLabel object by setting the rectangular bounds and using table.add(label);
image here
Where did you get the idea that you can do table.add(label) and hope that the label be magically painted over the table?
(Same ??? for #dpatch's answer.)
You have to use cell renderer/editor for any custom painting inside table. (Or layered pane/glass pane if it's something floating above table, but it looks like you want the labels in the cells.)
A crude renderer that paints cell (0, 0) as half-height blue on top of full-height red:
table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer()
{
private int row_ = 0;
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
row_ = row;
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
public void setUI(LabelUI ui)
{
super.setUI(new BasicLabelUI()
{
public void paint(Graphics g, JComponent c)
{
super.paint(g, c);
if( row_ == 0 )
{
Rectangle r = g.getClipBounds();
g.setColor(Color.RED);
g.fillRect(r.x, r.y, r.width, r.height);
g.setColor(Color.BLUE);
g.fillRect(r.x, r.y + 1, r.width, r.height/2 - 1);
}
}
});
}
});
Check out the following presentation. I think it talks about solution to similar problem
http://developers.sun.com/learning/javaoneonline/2008/pdf/TS-4982.pdf?cid=925395
When you find two labels that need to be in the same cell, create a JPanel with the red and blue labels each taking up half the height of the panel. Then just add the panel to the table.
Related
This is the Code I use to get the Cell of a Tile so I can delete it.
public TiledMapTileLayer.Cell getCell(){
TiledMapTileLayer layer = (TiledMapTileLayer)map.getLayers().get(1);
return layer.getCell((int)(body.getPosition().x * Constants.PPM / 32),
(int)(body.getPosition().y * Constants.PPM / 32));
}
The problem is I have a coin in my Bo2dWorld, which is 2x2 Cells big.
If I call this method it only deletes the Top-Right-Hand Corner Cell of the Coin Tile... But I want to delete all 4 Cells of the Coin.
Does anyone know how to do that?
The coin is 2x2 tiles big and you only return on of those tiles in your getCell()
One option is to ad a property to the coin tiles in Tiled. Call it something like "CoinTileCorner". Then call the 4 tiles "TopLeft", "TopRight", "BottomLeft" and "BottomRight".
Now when you get a cell returned from getCell you can check for the property and know which other tiles to remove with it.
private void removeCoin(cell){
String corner = cell.getTile().getProperties().get("CoinTileCorner");
if(corner.equals("TopLeft")){
//remove this cell, the cell to the right, below and the one bellow on the right.
else if(corner.equals("TopRight")){
//remove this cell, the one to the left... and so on and so forth.
}
}
I am writing an application, using a datagrid. Various rows are differing colors based on the data. When the user selects a row the color becomes a few shades lighter.
Unfortunately one of the users doesn't think it is enough of a contrast and would like a more noticeable visual indicator. My two thoughts are to either;
A) Draw a rectangle around the entire row selected.
B) Add a column with an image that I hide or make visible based on whether the row is selected.
I went down path A. for a while and got to the point where in the function;
override protected function drawHighlightIndicator
I was able to identify when I was looking at the specific row, but I couldn't determine how to draw the rectangle.
So I backtracked and looked into B. I am able to create an Item renderer with an arrow, but I can't figure out how to turn it on & off when selected. I have a click event in the main module, but no way to reference back to the Item renderer component.
I could set a value in the array collection, and do a refresh, which will probably work, but that tends to move the selected row to the top of the datagrid display area.
So if anyone can help I on A or B would appreciate it. This is a DataGrid, not an AdvancedDataGrid.
Since you're using mx.controls.DataGrid, overriding drawHighlightIndicator could look like following example, which draws 1px red border around selection marker:
protected function drawHighlightIndicator(
indicator:Sprite, x:Number, y:Number,
width:Number, height:Number, color:uint,
itemRenderer:IListItemRenderer):void
{
var width:int = unscaledWidth - viewMetrics.left - viewMetrics.right;
var borderColor:uint = 0xff0000;
var g:Graphics = Sprite(indicator).graphics;
g.clear();
g.beginFill(borderColor);
g.drawRect(0, 0, width, height);
g.beginFill(color);
g.drawRect(1, 1, width - 2, height - 2);
g.endFill();
indicator.x = x;
indicator.y = y;
}
I'm attempting to draw a triangle that has a grid inside. Much like graphing paper. I have the grid, and the triangle drawn, but I don't know how to remove the excess grid. The grid currently is drawn in a for loop until it gets to the end of the triangle's length. The problem is, this will draw a box 'grid' on top of the triangle. Can I draw on top of the excess to get rid of it? Should I draw the lines differently or draw multiple triangles inside the large one to simulate a grid? Assistance would be appreciated.
public class TrianglePanel extends JPanel{
final int pixelParameter = 20;
final int HEIGHT = 800, WIDTH = HEIGHT;
public TrianglePanel(){
setPreferredSize(new Dimension(WIDTH,HEIGHT));
setBackground(Color.white);
}
public void paint(Graphics g){
int [] xPoints = {0,WIDTH/2,0};
int [] yPoints = {HEIGHT,HEIGHT,HEIGHT/2};
g.drawPolygon(xPoints, yPoints, 3); // Draws the triangle
for (int i = pixelParameter; i < WIDTH/2; i += pixelParameter){
g.drawLine(i, HEIGHT, i, (HEIGHT/2)); // Draws vertical lines
g.drawLine(0, HEIGHT - i, (WIDTH/2), HEIGHT - i); // Draws horizontal lines
}
}
}
Custom painting is done by overriding the paintComponent() method, not the paint() method.
Don't forget to invoke super.paintComponent() at the start so the background gets painted.
Create a Polygon object. Then you can try using the Graphics.setClip(Shape) method before you attempt to draw the grid lines.
Hy everyone,
I'm trying to do some calculations in a JTable after iteration and mark with different background the cells that I need.
However, I have 2 problems at the moment:
1) Cells are not painted immediately, but after the whole iteration cycle
2) Areas are not painted properly - if I need to paint table[3, 4] and table[6, 5] it draws a rectangular from [3,4] up to [6, 5] instead of drawing the singular cells only.
About problem 1: could I call repaint() with priority without the need to finish everything and the JVM to decide whenever to paint? I try to do fireTableCellUpdated() and fireTableDataChanged() but they don't get updated.
Here there is my custom cell renderer method that changes the BGcolor:
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row,int column) {
Component renderer = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
if(value instanceof Color) {
Color c = (Color) value;
renderer.setBackground(c);
System.out.println("BG change [" + row + ":" + column + "]");
}
return renderer;
}
Here there is the loop where I paint my cells on a button click:
for(int paintJ = startIndex; paintJ < endIndex; paintJ++) {
CrossCellRenderer rend = (CrossCellRenderer) jTable1.getCellRenderer(i, paintJ)
.getTableCellRendererComponent(jTable1, Color.blue, true, true, i, paintJ);
crossTableModel.fireTableCellUpdated(i, paintJ);
jTable1.revalidate();
jTable1.repaint();
try {
Thread.sleep(1000);
} catch(InterruptedException ie) {
System.err.println("Exception sleeping the thread.");
}
}
Any tips on that?
Hate to say: but you do it (whatever you want to reach) completely wrong ;-)
Never-ever do any direct manipulation/paint on a renderer, instead change the model data and the rest will happen automatically.
Never-ever call any of the fireXX methods on a model from outside the model, it's the exclusive responsibility of the model to notify
its listeners on change
Never-ever (or very very rarely, certainly not here ;-) there's a need to call revalidate and/or repaint dircectly, will happen
automatically if a model is well-behaved
....
Best to read Snoracle's tutorial on howto-use tables to fully understand the rendering mechanism
http://download.oracle.com/javase/tutorial/uiswing/components/table.html
Roughly:
// change the model, will notify its listeners
model.setValueAt(....)
// in a custom renderer, check the value and decorate as appropriate
public Component getTableCellRendererComponent(....) {
// ... normal config, f.i. done in super
Component comp = super.get...
if (myConditionForSpecialColor(table, value, ...) {
comp.setBackground(myColor);
} else {
comp.setBackground(normalColor);
}
}
// register the custom renderer
// per class
table.setDefaultRenderer(Object.class, myRenderer)
// or per column
table.getColumnModel().getColumn(myColumn).setCellRenderer(myRenderer)
When i am declaring rows and columns to my gridlayout.eg: 3x2 (3 rows and 2 cols).I have to get a skeletal view of these rows and columns.Like a dotted rectangles.How can we achieve this by using swing ?
regards
Mathan
Add a Border to each of your components in the gridlayout.
Subclass a JPanel to draw a grid within paintChildren(). Any components you add to this panel will show this grid. For example:
public class DebugPanel extends JPanel {
#Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
g.setColor(Color.GRAY);
// dashed stroke
BasicStroke stroke = new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 1,new float[]{5},0);
((Graphics2D)g).setStroke(stroke);
drawComponentGrid(this,g);
}
/**
* Drawn vertical and horizontal guides for a containers child
* components
*/
private static void drawComponentGrid(Container c, Graphics g) {
for(int i=0;i<c.getComponentCount();++i) {
Rectangle r = c.getComponent(i).getBounds();
int x = r.x;
// vertical line at left edge of component
g.drawLine(x,0,x,c.getHeight());
x+= r.width;
// vertical line at right edge of component
g.drawLine(x,0,x,c.getHeight());
// horizontal line at top of component
int y = r.y;
g.drawLine(0,y,c.getWidth(),y);
// horizontal line at bottom of component
y+= r.height;
g.drawLine(0,y,c.getWidth(),y);
}
}
}