I'm trying to implement a bin packing algorithm using Next Fit online. So I don't know the size of the boxes before hand. Anyway I had a Box class with height and width. A column class which represents and stack of boxes and a Truck class which holds the stacks of boxes and a boolean if the truck is full or not.
However when I'm in my test class I generate a list of boxes and a list of trucks to hold the boxes. I add the boxes to each truck, when the truck is almost out of space, the final box tries to get added, and it doesn't fit, so the boolean isFull is set to true, but the box that went into the method is then lost. How can I add the box to the truck and if its full, use the same box on a call on the next truck?
Many Thanks
code
public void addBoxesNextFit(Box b)
{
if(truck.isEmpty()) // easy first case
{
*make a new column*
*add box to column and add column to truck*
}
else
{
*Get the last column in list*
if(remainingHeight in column > BoxesHeight && widthOftheColumn > boxesWidth)
{
*add box to column*
*add column to truck*
boxesInTruck++;
}
else if(there is enough space to make another column with the box)
{
*Make new column*
*add box to column and column to truck*
boxesInTruck++;
widthofAllColumns += b.getWidth(); //update width of all columns
}
else
{
truckFull = true; // if u can't add the box to 1 of the columns and you can't create a new column
} // then the truck is full
}
}
Related
I've just started with java so bear with me if I confuse things.
Anyway, I want to create a level that contains 4 different rooms. I've done it so that every room is a seperate object which is created in the main method.
What I want to do then is to place every room inside a level of a certain size, and if a room overlaps another it will return false. Every room is basically a block of 100x100 pixels.
I've done so that every room object stores it's location on the level when placed by assigning the (x,y) cords to 2 variables defined within the room class.
But I run into trouble when placing the second room. How do I check if the second room I want to place doesn't overlap with the others? My tought was that you check all the (x,y) variable values in all the room objects and if any of them overlaps it will return false. However I don't know how to refer to all these variables, how can I check the variables in every room object?
Thank you so much for your help!
Place the rooms that are assigned to a place in an ArrayList, so you can loop through them and compare the parameters. I suppose a room does not only have x and y coordinates, but also length and width.
// using a list of rooms that are placed on level
List<Room> assignedRooms = new ArrayList<Room>();
// create a new room (x, y, width, height)
Room newRoom = new Room(0, 0, 100, 100);
assignedRooms.add(newRoom);
// create further rooms
In order to find out whether a room overlaps with another one or not, you best loop through the remaining rooms, i.e., the ones you have already placed within the whole area and check if the x and y coordinates of the newly added room are in conflict with any of the other rooms.
for (int i = 0; i < assignedRooms.size(); i++) {
Room assignedRoom = assignedRooms.get(i);
if (assignedRoom.x < roomToAdd.x && assignedRoom.x + assignedRoom.width > roomToAdd.x)
// overlap
return false;
else if (assignedRoom.y < roomToAdd.y && assignedRoom.y + assignedRoom.height > roomToAdd.y)
// overlap
return false;
}
return true;
I figured out how to drag to highlight multiple cells in a GridLayout-designed grid (which wasn't too hard) and how to drag a cell from one such grid to another (which involved brute force and math, but it turned out not to be all that hard, either).
But the code looks and feels hacked.
How should I have done it?
Here are code fragments that typify what I did to drag content (one char):
For each cell in txtUser[] grid add mouse listener to identify the cell about to be dragged and also access its content:
txtUser[i].addMouseListener(new java.awt.event.MouseListener()
{
public void mousePressed(MouseEvent e) {
currentUserCell.index = interp(e.getXOnScreen(), ulcUser.x, txtUser[0].getWidth());
if(txtUser[currentUserCell.index].getText().length() > 0)
currentUserCell.content = txtUser[currentUserCell.index].getText().charAt(0);
}
Here's interp(), which converts from absolute screen pixel (x) to (returned) grid element number, given the upper-left corner of the text field array and the width of one element:
static int interp(int x, int ulc, int w){
return (x - ulc)/w;
}
If the user moves the frame, interp() above doesn't work, requiring need to reorient():
void reorient(){
ulcGrid = new Point(cells[ 0][ 0].getLocationOnScreen().x, cells[ 0][ 0].getLocationOnScreen().y);
ulcUser = new Point(txtUser[ 0] .getLocationOnScreen().x, txtUser[ 0] .getLocationOnScreen().y);
}
(I tried to use relative pixel locations, but couldn't make it work. I may revisit this.)
In order to drop the dragged content, the destination had better be inbounds():
boolean inbounds(int r, int c){
return ! (r >= N || c >= N || r < 0 || c < 0);
}
If inbounds, the letter is dropped, as long as destination is empty:
public void mouseReleased(MouseEvent e) {
int x, y;
if(! dragging)
return;
dragging = false;
x = e.getLocationOnScreen().x;
y = e.getLocationOnScreen().y;
int c = Utilities.interp(x, ulcGrid.x);
int r = Utilities.interp(y, ulcGrid.y);
if(! inbounds(r, c))
return;
if(cells[r][c].getText().length() > 0)
return;
cells[r][c].setText("" + currentUserCell.content);
The previous method required a MouseMotionAdapter for each cell of the source array.
And it just seems so hacked. One reason I say this is that I rely on several global variables, such as ulcGrid and ulcUser and currentUserCell and dragging:
private void txtUserMouseDragged(MouseEvent evt)
{
dragging = true;
}
I had a nice learning experience, but I'd rather have more-professional-looking code, most notably with fewer global variables. (I realize that a good start would be to not rely on absolute pixel addresses.)
So I'm asking where to find a better way, specifically how to identify the drag source and destination cells of a one- or two-dimensional array of text fields.
=================
--EDIT--
My program works. My question is about whether there is a library that would make it easier and more reliable than what I've written to drag from the one-dimenional array at the bottom of the screen below onto the large grid.
But now that I've read the comments, maybe this is just another bad question that should be deleted.
My intention is to use the ListCellRenderer in order to highlight red cells that contain links that have been visited(or clicked) and green those which have not been visited this works partially but not quite. It seems that the renderer works as far as it concerns marking the cells red. If I however add more rows, they come all red colored thereafter. In addition if I mark two cells that are not adjacent then it marks them all red as well.
I have a class Feed, where I initially had a boolean variable, but I have modified the code so that the m_isRead variable is in the listModel here is the constructor:
public Feed (URL url, String urlName) {
this.m_urlName = urlName;
this.m_observers = new ArrayList<Observer>();
this.m_isRead = isRead;
}
Now this instance variable is set to false in the listModel Class which is the one that contains the renderer.
m_isRead = false.
When using the ListCellRenderer which I now have adjusted so that it does not require this method:
m_feeds.get(index).getM_urlName();
I proceed as follows:
class MyCellRenderer extends JLabel implements ListCellRenderer {
public MyCellRenderer() {
setOpaque(true);
}
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
setText(value.toString());
Color background = Color.GREEN;
Color foreground = Color.BLACK;
//find out if the specific has been read or not
if (m_feeds.get(index).isM_isRead() == true) {
background = Color.RED;
foreground = Color.WHITE;
} else {
background = Color.GREEN;
foreground = Color.BLACK;
};
setBackground(background);
setForeground(foreground);
return this;
}
}
Then I have another inner class with a method which I use to get the selected item, at that point I set m_isRead to true (to read) this is now independent from the Feed class and the code which related to it has been commented out:
public class ChangeSelectedIndex implements ListSelectionListener {
#Override
public void valueChanged(ListSelectionEvent e) {
for (int i = 0; i < m_listModel.size(); i++) {
if (m_listModel.getElementAt(i) != null) {
m_urlName = m_list.getSelectedValue();
initiateParsing();
m_updateFeedButton.setEnabled(true);
// TODO fix behavior for cell renderer
//this sets the value of the feed being clicked to true
// m_feeds.get(i).setM_isRead(true);
m_isRead = true;
}
}// end for
}
}
Now the result is the same, if I add the rows they are green and that is correct, if I click on each row each turns read provided that I have clicked the adjacent rows to the first one I click but if I, for example, have four rows and I click the first row and the last row, all the rows, including those in between (which I have not clicked) turn red. Likewise, if I add new rows they come in red. That is if I click even one of those rows then the ones I add thereafter will be red.
Can anybody help?
Thank you in advance,
Cheers
After a while thinking about it I have concluded that there was nothing wrong my original cell renderer, it has had to do with the list model itself. The JList simply did not support multiple NON contiguous selection without clicking the Ctrl button right out of the box. This is what triggered further searching on my side on how to emulate the Ctrl click down; which I found here on answer number 8 (working code):
Individual and not continuous JTable's cell selection
The interesting here is adding the mouse event to the list. This mouse event emulates a Ctrl down event, which the ListSelectionModel which is used by JList as well as JTable is set to MULTPLE_SELECTION_INTERVAL it behaves as desired. That is, the user now able to click on whatever feed, even if it is not contiguous, and it will color the desired feed or feeds without coloring whatever unclicked feed may lay in between.
As for the renderer, it would suffice to use the isSelected parameter which comes in through with its method getListCellRenderer(). However, in my case, what I had done has the same effect with the addition that I was using an array to add all the statuses of the feeds, meaning, read or unread. Proceeding this way, I had in mind that if I closed the program and save the feed list, including its isRead parameter set to either true or false, then later on upon retrieving the feed list, the same feed status would be restored from, for example, a file, or at least that is what I had in mind.
I'm looking for the way to handle the cell click. How to do this if I create a new column in grid in this way:
column = new ColumnConfig();
column.setId("remove");
column.setHeader("Remove");
column.setWidth(100);
configs.add(column);
?
You have to handle cell clicks on the grid to which the ColumnConfig belongs.
For example, say you have Grid grid = new Grid(new ColumnModel(column));, then:
grid.addListener(Events.CellDoubleClick, new Listener<GridEvent>() {
public void handleEvent(GridEvent be) {
// be.getColIndex() gets the index of the column clicked on.
// if you know the index of `column`, you can compare that number to the colIndex
// if the numbers are equal, do whatever you want to do
// see docs for GridEvent at
// http://dev.sencha.com/deploy/gxt-2.2.5/docs/api/com/extjs/gxt/ui/client/event/GridEvent.html
}
});
I am using Custom Data Grid from GWT showcase example ..
http://gwt.googleusercontent.com/samples/Showcase/Showcase.html#!CwCustomDataGrid
Every thing is working fine ..I have sub Rows inside my rows in the cell table ..
I have anchor cell.. which are in the main row and in the sub row ..
the ClickHandler for the main row is working but not in the sub row ..
this is my code for that cell
// ViewDetail.
td = row.startTD();
td.className(cellStyles);
td.style().trustedColor("blue");
td.style().cursor(Cursor.POINTER);
if (isNetworkRow) {
//td.text("subRowsAnchor");
} else {
}
renderCell(td, createContext(19), viewDetailsColumn, rowValue);
I am rendering the cell in both cases , either its a row or sub row
so i can see the anchor and its clickHandler also works ..
Is there any way i can differentiate that which anchor is been clicked ,, main rows or sub row's.
I just tried to make a small work around . i.e changing the name of the anchor text if its a sub row .. as u can c in my code ..td.text..
but then get the error on renderCell...
Attributes cannot be added after appending HTML or adding a child element.
Any idea , what could be solution...
thanks
To distinguish between which row has been clicked (according to the showcase sample, but should be the same in general), simply rely on which row has been selected (provided that you haven't overridden/disabled the selection handling).
Set up a FieldUpdater to the column (that renders itself using your anchor cell) and check for the subrow selection using getKeyboardSelectedSubRow(). Something like:
yourColumn.setFieldUpdater(new FieldUpdater<T, String>() {
public void update(int index, T object, String value) {
if (yourGrid.getKeyboardSelectedRow() != -1 ) {
if (yourGrid.getKeyboardSelectedSubRow() > 0) {
// Subrow selected.
} else {
// Main row selected.
}
}
}
});